Qt学习笔记(持续更新)

第一个应用程序

#include "widget.h"
#include <QApplication>
#include<QLabel>
int main(int argc, char *argv[])
{//创建qt应用程序对象QApplication a(argc, argv);//创建标签控件QLabel label("你好");//来吧,展示label.show();Widget w;w.show();//让应用程序进入事件return a.exec();
}

Qt中文编码问题

Qt内部编码:

  • Qt应用程序编程接口及其内部实现所使用的字符,都是以unicode编码(UTF-16),也就是Unicode就是Qt的内部编码

外部编码:

  • 程序源代码中使用的字面值形式的字符和字符串、用户通过程序界面输入的字符和字符串,以及程序通过文件、网络、进程间通信或其它媒介读取的字符和字符串,受系统环境等因素的影响,通常会是各种各样的编码格式,一般将其统称为外部编码
QString::QString(const char *str)
/*Constructs a string initialized with the 8-bit string str. The given const char pointer is converted to Unicode using the fromUtf8() function.*/

编码转换

  • 默认情况下,Qt5可以正确理解uft-8格式编码,并将其自动转换为内部的unicode编码,如果使用utf-8的中文字符串总是能够正确显示,但是如果使用其它格式的外部编码,比如windows中常用的GBK编码,将会出现乱码现象
  • 通过QTextCodec实现编码转换 QTextCodec *codec =QTextCodec::codecForName(“GBK”);
  • QString string = codec->toUnicode (“GBK编码的中文字符串”);
    所以我们需要尽量使用UTF8

父窗口

-创建控件时,可以指定停靠在某个父窗口上面,这时控件将作为子窗口被束缚在其父窗口的内部,并伴随父窗口一起移动、隐藏、显示和关闭;否则该控件将作为独立窗口显示在屏幕上,且游离于其它窗口之外

QWidget及其子类的对象可以做为其它控件的父窗口常用的父窗口类又如下三个∶

  • QWidget
  • QMainWindow(主窗口)//QWidget的直接子类
  • QDialog(对话框)//QWidget的直接子类

父窗口的析构函数回自动销毁其所有的子窗口对象,因此即使子窗口对象是通过new操作符动态创建的,可以不显式的执行delete操作,而且不用担心内存泄漏的问题,只要保证父窗口对象被正确销毁,其子窗口也将随之被销毁

#include "widget.h"
#include <QApplication>
#include<QLabel>
#include<QDialog>
#include<QMainWindow>
#include<QPushButton>int main(int argc, char *argv[])
{QApplication app(argc,argv);
//   QWidget parent;QDialog parent;
//   QMainWindow parent;parent.move(50,50);parent.resize(320,320);QLabel label("我是标签",&parent);label.move(20,40);QPushButton button("我是按钮",&parent); //栈对象button.move(20,100);button.resize(80,80);QPushButton* button2 = new QPushButton("我是按钮",&parent); //堆对象parent.show();//让应用程序进入事件return app.exec();
}

信号和槽

  • 信号和槽是QT自行定义的一种通信机制,实现对象之间的数据交互。当用户或系统触发了一个动作,导致某个控件的状态发生了改变,该控件就会发射一个信号,即调用其类中一个特定的成员函数(信号),同时还可能携带有必要的参数
  • 槽和普通的成员函数几乎没有太多区别,可以是公有的、保护的或私有的,可以被重载,也可以被覆盖,其参数可以是任意类型,并可以像普通成员函数一样调用
  • 槽函数与普通成员函数的差别并不在于其语法特性,而在于其功能。槽函数更多体现为对某种特定信号的处理,可以将槽和其它对象信号建立连接,这样当发射信号时,槽函数将被触发和执行,进而来完成具体功能

信号的定义:

信号的定义
class XX:public QObject
{
Q_OBJECT
signals:void signal_func(..);//信号函数
};

信号函数只需声明,不能写定义
槽的定义:

class xx:public QObject{
Q_OBJECT
public slots:
void slot_func(...){...}//槽函数
};
注︰槽函数可以连接到某个信号上,当信号被发射时,槽函数将被触发和执行,另外槽函数也可以当做普通的成员函数直接调用

信号和槽的连接:

QObject::connect( const QObject * sender, const char * signal
const Qobject * receiver, const char * method) ;
参数:
sender:信号发送对象指针
signal:要发送的信号函数,可以使用“SIGNAL(..)”宏进行类型转换
receiver:信号的接收对象指针
method:接收信号后要执行的槽函数,,可以使用“SLOT(..)宏进行类型转换
   //点击按钮关闭窗口QObject::connect(&button,SIGNAL(clicked(void)),&label,SLOT(close()));//增加退出按钮,实现退出QObject::connect(&button3,SIGNAL(clicked(bool)),&parent,SLOT(close()));

信号和槽连接的语法要求:
信号和槽连接的语法要求信号和槽参数要一致

Q0bject:connect(A,SIGNAL(sigfun(int)), B,SLOT(slotfun(int)));//ok
Q0bject:connect(A,SIGNAL(sigfun(int)), B,SLOT(slotfun(int,int));//error
  • 可以带有缺省参数
Q0bject:connect(A,SIGNAL(sigfun(int)), B,SLOT(slotfun(int,int=O)));//ok
  • 信号函数的参数可以多于槽函数,多余参数将被忽略
QObject::connect(A,SIGNAL(sigfun(int,int)),B,SLOT(slotfun(int));//ok
  • 一个信号可以连接多个槽(但是执行顺序不确定)
  • 多个信号可以连接一个槽
  • 两个信号可以直接连接(信号级联),应用比较少。

一个小例子


int main(int argc, char *argv[])
{QApplication app(argc,argv);QDialog parent;parent.resize(320,240);//创建水平滑块QSlider slider(Qt::Horizontal,&parent);slider.move(20,100);slider.setRange(0,200);//创建选址框QSpinBox spin(&parent);spin.move(220,100);spin.setRange(0,200);//滑块滑动影响选址框QObject::connect(&slider,SIGNAL(valueChanged(int)),&spin,SLOT(setValue(int)));QObject::connect(&spin,SIGNAL(valueChanged(int)),&slider,SLOT(setValue(int)));parent.show();//让应用程序进入事件return app.exec();
}

关于面向对象的Qt编程

没啥好说的,实现一个加法计算器吧

加法计算器

  • 通过面向对象的编程思想实现加法计算器
  • 输入两个数字,按“=”按钮显示计算结果
  • 两个操作数必须都是合法的数字,拒绝接受任何非法字符
  • 两个操作数必须全部合法,“=”按钮才被激活,否则禁用(不可以点击)
  • 显示结果的控件只可查看不可修改,但支持复制到剪贴板
  • 所有子窗口的大小和位置随主窗口的缩放自动调整至最佳

写了半个多小时,IDE卡死了,你码没了!!!!!!!!!!!!艹

Time::Time(QWidget *parent): QWidget(parent)
{ui.setupUi(this);//初始化界面m_label = new QLabel(this);m_label->setFrameStyle(QFrame::Panel | QFrame::Sunken);m_label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);//设置字体大小QFont font;font.setPointSize(20);m_label->setFont(font);//获取系统时间按钮m_button = new QPushButton("get time", this);m_button->setFont(font);//垂直布局器QVBoxLayout* layout = new QVBoxLayout(this);layout->addWidget(m_label);layout->addWidget(m_button);setLayout(layout);//信号和槽connect(m_button, SIGNAL(clicked()),this, SLOT(getTime()));
}void Time::getTime()
{qDebug() << "gettime";//获取当前时间QTime time = QTime::currentTime();//将时间转换为字符串形式QString str =  time.toString("hh:mm:ss");//显示时间m_label->setText(str);}
class Time : public QWidget
{Q_OBJECT public:Time(QWidget *parent = Q_NULLPTR);private:Ui::TimeClass ui;
private:QLabel* m_label;QPushButton* m_button;
public slots://获取系统时间槽函数void getTime(void);
};

有缺陷,但我不想改了。

Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);connect(ui->m_btnBox,SIGNAL(accepted()),this,SLOT(onAccepted()));connect(ui->m_btnBox,SIGNAL(accepted()),this,SLOT(onRejected()));
}Widget::~Widget()
{delete ui;
}
//处理OK
void Widget::onAccepted(void)
{if(ui->m_usernameEdit->text() == "123" &&ui->m_passwdEdit->text() == "123"){qDebug()<<"登陆成功";close();//关闭窗口}else{QMessageBox msgBox(QMessageBox::Critical,"Error","用户名或密码错误",QMessageBox::Ok,this);msgBox.exec();}}//处理取消
void Widget::onRejected(void)
{QMessageBox msgBox(QMessageBox::Question,"登录","是否确定要取消登录",QMessageBox::Yes | QMessageBox::No,this);if(msgBox.exec() == QMessageBox::Yes){close();}}

Qt的事件处理机制

什么是事件?

  • 在Qt中,是以事件驱动UI工具集,包括信号和槽都依赖于Qt的事件处理机制
  • 通常事件是由窗口系统或者Qt自身产生的,用以响应所发生的各类事情,比如用户按下并释放了键盘或者鼠标、窗口因缩放而需要重绘、定时器到期而应有所动作

如何处理事件?

  • 在Qt中,事件被封装成对象,所有的事件对象类型都继承自抽象类QEvent

  • 当事件发生时,首先被调用的是Q0bject类中的虚函数event(),其参数(QEvent)标识了具体的
    心事件类型

  • 在Qt桌面应用(Qt Widgets Application)开发中,QWidget类覆盖了其基类中的event()虚函数,并根据具体事件调用具体事件处理函数︰

  • 所有的事件处理函数都是虚函数,可以被QWidget的子类覆盖,以提供针对不同窗口控件类型的事件处理,控件的使用者所关心的往往是定义什么样的槽处理什么样的信号,而控件的实现者则更关心覆盖哪些事件处理函数

  • 如果程序员希望在窗口中自定义的处理事件,可以继承QWidget或者其子类,比如QDialog.QMainWindow,在自定义的窗口子类中重写事件处理函数,当相应事件被触发时,会利用多态的语法机制,所执行到的事件处理函数将是子类中重写的版本,从而实现程序员先要的事件处理效果
    案例:

//槽函数
void ShowimageDialog::on_m_btnPrev_clicked()
{if(--m_index<0){m_index = 8;}update();
}void ShowimageDialog::on_m_btnNext_clicked()
{if(++m_index>8){m_index = 1;}update();
}
//斜体字是虚函数
void ShowimageDialog::paintEvent(QPaintEvent*)
{//qDebug("paintEvent");// 1)创建爱你画家对象QPainter painter(this);// 2)获取绘图所在的矩形区域QRect rect = ui->frame->frameRect();//坐标值得平移,奇妙的语法rect.translate(ui->frame->pos());// 3)构建要绘制的图形对象QImage image(":/images/1 ("+QString::number(m_index)+").jpg");// 4) 使用painter将image图片画到rectpainter.drawImage(rect,image);
}

定时器

定时器事件
Qt通过两套机制为应用程序提供定时功能

  • 定时器事件,由Q0bject提供
  • 定时器信号,由QTimer提供>通过定时器事件实现定时器
  • int Q0bject.startTimer (int interval;启动定时器,以后每隔interval毫秒触发一次定时器事件,返回定时器ID
  • void Qobject:timerEvent (QTimerEvent* ) [virtual];//定时器事件处理函数.
  • -void Qobject::killTimer(int id);//关闭参数id所标识的定时器
#include "erinedialog.h"
#include "ui_erinedialog.h"ErineDialog::ErineDialog(QWidget *parent) :QDialog(parent),ui(new Ui::ErineDialog)
{ui->setupUi(this);m_index = 0;isStarted =false;qsrand(QTime::currentTime().msec());//加载所有图片到容器loadPhotos("./photos");qDebug()<<"加载图片个数"<<m_vecPhotos.size();}ErineDialog::~ErineDialog()
{delete ui;
}void ErineDialog::on_pushButton_clicked()
{if(isStarted == false){isStarted = true;m_timer =startTimer(50);ui->pushButton->setText("停止");}else{isStarted = false;killTimer(m_timer);ui->pushButton->setText("开始");}}//加载图片容器功能
void ErineDialog::loadPhotos(const QString& path)
{QDir dir(path);//便利当前目录下所欲图片QStringList list1 =  dir.entryList(QDir::Files);for(int i = 0;i<list1.size();i++){QImage image(path+"/"+list1.at(i));m_vecPhotos<<image;//保存到容器}QStringList list2 = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);for(int i = 0 ;i<list2.size();i++){loadPhotos(path+"/"+list2.at(i));}
}//定时器事件处理函数
void ErineDialog::timerEvent(QTimerEvent *)
{m_index =  qrand() % m_vecPhotos.size();update();
}//绘图事件处理函数
void ErineDialog::paintEvent(QPaintEvent*)
{QPainter painter(this);QRect rect = ui ->frame->frameRect();rect.translate(ui->frame->pos());painter.drawImage(rect,m_vecPhotos[m_index]);}
#ifndef ERINEDIALOG_H
#define ERINEDIALOG_H#include <QDialog>
#include <QTime>
#include <QPainter>
#include <QDir>
#include <QTime>
#include <QVector>
#include <QImage>
#include <QDebug>namespace Ui {
class ErineDialog;
}class ErineDialog : public QDialog
{Q_OBJECTpublic:explicit ErineDialog(QWidget *parent = 0);~ErineDialog();private slots:void on_pushButton_clicked();private:Ui::ErineDialog *ui;QVector<QImage> m_vecPhotos;//保存图片的容器int m_index;//图片在容器中的索引int m_timer;//定时器bool isStarted;//标记摇奖机的状态,真 正在摇奖 假 没摇奖
private://加载图片容器功能void loadPhotos(const QString& path);//定时器事件处理函数void timerEvent(QTimerEvent *);//绘图事件处理函数void paintEvent(QPaintEvent*);};#endif // ERINEDIALOG_H

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/408218.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文本框宽度自动适应文本宽度

<html> <head> <title>文本框宽度自动适应文本宽度 </title> </head> <script type"text/javascript"> function changeInputlength(cursor) { var getTextdocument.getElementById("text"); cursor.sizegetText.valu…

安装了一次Linux,哈哈

昨天在宿舍里&#xff0c;舍友在她的机子上装了Redhat&#xff0c;自己在旁边和另一舍友做参谋&#xff0c;哈哈&#xff0c;虽然中间几多挫折&#xff0c;但最终还是把系统装好了&#xff0c;第一次完整的安装Linux&#xff0c;在此记录一下&#xff0c;哈哈…… 现在想…

Ubuntu NFS搭建过程

简介 NFS:是Network FileSystem。最大的作用就是通过网络&#xff0c;让不同的机器、不同的作业系统、可以分享档案。通过将共享目录挂接到本地&#xff0c;就可以像操作本地目录一样去操作共享的目录。在共享中分为服务器和客户端,需要安装的程序也不一样&#xff0c;客户端通…

Unicode简介【转】

Unicode是一种字符编码规范 。先从ASCII说起。ASCII是用来表示英文字符的一种编码规范&#xff0c;每个ASCII字符占用1个字节&#xff08;8bits&#xff09; 因此&#xff0c;ASCII编码可以表示的最大字符数是256&#xff0c;其实英文字符并没有那么多&#xff0c;一般只用前12…

C++17新特性学习笔记

c17最新特性笔记 1.基本语言特性 ​ 这一部分介绍了 C17中新的核心语言特性&#xff0c;但不包括那些专为泛型编程&#xff08;即 template&#xff09;设计的特性。 结构化绑定 结构化绑定允许你用一个对象的元素或对象初始化多个实例(第一眼感觉Python解包很像) 这有一个…

教你如何写框架------用中文构建脚本

框架下载地址&#xff1a; http://files.cnblogs.com/zhangfei/Automation.rar 在看此篇博文前请先理清如下两下博文, 该博文是建立在如下两篇文章的基础上的&#xff1a; http://www.cnblogs.com/zhangfei/p/3456159.htmlhttp://www.cnblogs.com/zhangfei/archive/2012/10/10/…

配置MIME一览

用JSP写WML&#xff1a;Code:<% page contentType"text/vnd.wap.wml; charsetGBK" %> <?xml version"1.0"?> <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.WAPforum.org/DTD/wml_1.1.xml"> …

滚动条添加事件

1、 <script type"text/javascript"> $(document).ready(function (){ var nScrollHight 0; //滚动距离总长,即750px var nScrollTop 0; //滚动到的当前位置 var nDivHight $("#div1").height(); //即500px …

C++三路比较运算符

左操作数 <> 右操作数 表达式返回一个对象&#xff08;其实是这个std::strong_ordering&#xff09;&#xff0c;使得 若 左操作数 < 右操作数 则 (a <> b) < 0 若 左操作数 > 右操作数 则 (a <> b) > 0 而若 左操作数 和 右操作数 相等/等价…

使用WSE实现Web Service安全

WSE(Web Services Enhancements)是微软为了使开发者通过.NET创建出更强大&#xff0c;更好用的Web Services而推出功能增强插件。现在最新的版本是WSE2.0(SP2).本文描述了如何使用WSE2.0中的安全功能增强部分来实现安全的Web Services。WSE的安全功能增强实现的是WS-Security标…

spring之:XmlWebApplicationContext作为Spring Web应用的IoC容器,实例化和加载Bean的过程...

它既是 DispatcherServlet 的 (WebApplicationContext)默认策略&#xff0c;又是 ContextLoaderListener 创建 root WebApplicationContext(根容器&#xff0c;同时也是 DispatcherServlet 的 WebApplicationContext 的父容器)的默认策略。 继承体系 一、XmlWebApplicationCont…

C++17代码整洁之道

C17代码整洁之道 C代码整洁的基本规范 良好的命名 名称应该自解释使用域中的名称避免使用匈牙利命名法(即名称前加类型)不要通过注释禁用代码 函数 只做一件事情 函数体量要小 当你为函数找到一个富有表现力的名称时,名称中没有连词 圈复杂度低 函数的参数要少 函数尽…

使用.NET Remoting开发分布式应用——基于租约的生存期(转载)

使用.NET Remoting开发分布式应用——基于租约的生存期一&#xff0e;概述知名类型的SingleCall对象可以在客户程序的方法调用之后被垃圾收集器清理掉&#xff0c;因为它没有保持状态&#xff0c;属于无状态的。而客户激活的类型的对象和知名类型的SingleTon对象都属于生存期长…