高级控件
QListWidget
列表展示控件
效果
添加数据
ui->listWidget->addItem("A");
QStringList list;
list << "B" << "C" << "D";
ui->listWidget->addItems(list);
设置item点击
void Widget::on_listWidget_itemClicked(QListWidgetItem *item)
{
//获取item中的内容
qDebug() << item->text() << endl;
//获取选中的item在qlistwidget中的位置
qDebug() << ui->listWidget->currentRow() << endl;
}
QTreeWidget
//添加数据
//创建一级item
QStringList list;
list << "测试";
QTreeWidgetItem *item = new QTreeWidgetItem(list,0);
//创建二级item
QStringList list2;
list2 << "翠花" << "女" << "22";
QTreeWidgetItem *sonItem = new QTreeWidgetItem(list2,0);
//将二级item添加到一级item中
item->addChild(sonItem);
//将一级item添加到控件中
ui->treeWidget->addTopLevelItem(item);
//item点击事件
void Widget::on_treeWidget_itemClicked(QTreeWidgetItem *item, int
column)
{
qDebug() << item->text(column) << endl;
}
QTableWidget
for(int i = 0; i < 10; i++)
{
QString name = "张三";
//QString::number(i)数字转字符串
name.append(QString::number(i));
//新建行
int row = ui->tableWidget->rowCount();
//插入行
ui->tableWidget->insertRow(row);
//创建item
QTableWidgetItem *itemName = new QTableWidgetItem(name);
//给row行的第0个位置设置为itemName
ui->tableWidget->setItem(row,0,itemName);
QTableWidgetItem *itemSex = new QTableWidgetItem("男");
ui->tableWidget->setItem(row,1,itemSex);
QTableWidgetItem *itemAge = new QTableWidgetItem("18");
ui->tableWidget->setItem(row,2,itemAge);
QTableWidgetItem *itemAddress = new QTableWidgetItem("北方");
ui->tableWidget->setItem(row,3,itemAddress);
}
点击事件
void Widget::on_tableWidget_cellClicked(int row, int column)
{
qDebug() << "row:" << row << endl;
qDebug() << "column:" << column << endl;
qDebug() << "text:" << ui->tableWidget->item(row,column)->text() <<
endl;
}
QtoolBox
直接将内容拖拽到里面即可
QTabWidget
直接将内容拖拽到里面即可
QStackWidget
直接将内容拖拽到里面即可
void Widget::on_btn01_clicked()
{
ui->stackedWidget->setCurrentIndex(0);
}
void Widget::on_btn02_clicked()
{
ui->stackedWidget->setCurrentIndex(1);
}
void Widget::on_btn03_clicked()
{
ui->stackedWidget->setCurrentIndex(2);
}
自定义控件
目的
将多个控件或窗口作为一个整体
,
使其可以多次复用
步骤
1,
创建一个设计师界面类
2,
在该类中编写需要提出的自定义组件样式与代码
,
如下
代码
:
头文件
form.h
#ifndef FORM_H
#define FORM_H
#include <QWidget>
#include <QSpinBox>
#include <QHBoxLayout>
#include <QString>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = 0);
~Form();
void setValue(int num);
int getValue();
private:
Ui::Form *ui;
};
#endif // FORM_H
代码
:
源文件
form.cpp
#include "form.h"
#include "ui_form.h"
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
connect(ui->spinBox,SIGNAL(valueChanged(int)),
ui->horizontalSlider,SLOT(setValue(int)));
connect(ui->horizontalSlider,SIGNAL(valueChanged(int)),
ui->spinBox,SLOT(setValue(int)));
}
Form::~Form()
{
delete ui;
}
void Form::setValue(int num)
{
if(num < 0 || num > 99)
{
throw 0;
}
ui->spinBox->setValue(num);
}
int Form::getValue()
{
return ui->spinBox->value();
}
3,
在使用该自定义控件的界面中添加一个
QWidget,
用于容纳该自定义组件
,
并点击右键
提升为
输入步骤
1
中自定义的类名称
点击添加
点击提升
如
widget
窗口
代码头文件
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_pushButton_clicked();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
代码源文件
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
ui->widget->setValue(50);
}
事件
概述
Qt
中所有事件类都继承于
QEvent
。
event()
函数并不直接处理事件,而是按照事件对象的类型分派给特定的事件处理函
数。
示例:
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QMouseEvent>
#include <QDebug>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::mouseMoveEvent(QMouseEvent *event)
{
qDebug() << "鼠标移动:\tx=" << event->x() << "\ty=" << event->y() <<
endl;
}
void Widget::mousePressEvent(QMouseEvent *event)
{
qDebug() << "鼠标按下" << endl;
}
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
qDebug() << "鼠标抬起" << endl;
}
事件分发器
概述
事件对象创建完毕后,
Qt
将这个事件对象传递给
QObject
的
event()
函数。
event()
函数并不直接处理事件
,
而是将这些事件对象按照它们不同的类型
,
分发给不同
的事件处理器
(eventhandler)
如上所述,
event()
函数主要用于事件的分发。如果你希望在事件分发之前做一些操作
,
就可以重写这个
event()
函数
对应函数
virtual bool event(QEvent *e)
注意
:
如果传入的事件已被识别并且处理,则需要返回
true
,否则返回
false
。如果返回值是 true
,那么
Qt
会认为这个事件已经处理完毕,不会再将这。个事件发送给其它对象,而是会继续处理事件队列中的下一事件
事件过滤器
概述
步骤
this->installEventFilter(this);
2,
重写事件过滤器函数
bool MyLabel::eventFilter(QObject *watched, QEvent *event)
{
//判断哪个控件触发了
if(watched == this)//当前控件
{
//判断具体事件
if(event->type() == QEvent::MouseButtonPress)
{
QMouseEvent *ev = (QMouseEvent *)event;
qDebug()<<事件过滤器中 鼠标按下了x=<<ev->x()<<, y=<<ev->y()
<<endl;
return true;
}
}
return QLabel::eventFilter(watched, event);
}
绘图
概述
整个绘图系统基于
QPainter
,
QPainterDevice
和
QPaintEngine
三个类。
绘制窗口图形时在绘图事件中
绘图事件:
virtual void paintEvent(QPaintEvent *event)
绘图事件触发时机:
1,
窗口加载
2,
调用
update()
示例
:
页面背景绘制
void Widget::paintEvent(QPaintEvent *ev)
{
//
创建画家
QPainter *painter = new QPainter(this);
//
定义绘图设备
QPixmap pix;
//
加载图片
pix.load(":/image/Sunny.jpg");
//
设置大小
pix.scaled(this->width(),this->height());
//
绘制
painter->drawPixmap(0,0,this->width(),this->height(),pix);
}
定时器
分类
定时器事件
定时器对象
延迟执行
定时器事件
步骤:
1,
在头文件中声明
int
型变量用于记录定时器
id
2,
在头文件中声明定时器事件函数
3,
在源文件中开启定时器
4,
重写定时器事件函数
相关函数:
开启定时器
int startTimer(int interval, Qt::TimerType timerType =
Qt::CoarseTimer)
停止定时器
void killTimer(int id);
定时器事件函数
virtual void timerEvent(QTimerEvent *e)
示例
1:10
秒倒计时
//
在头文件中定义定时器
id
与要重写的定时器函数
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace
Ui
{
class
Widget
;
}
class
Widget
:
public
QWidget
{
Q_OBJECT
public
:
explicit
Widget
(
QWidget
*
parent
=
0
);
~Widget
();
virtual
void
timerEvent
(
QTimerEvent
*
e
);
private
:
Ui::Widget
*
ui
;
int
id
;
};
#endif
// WIDGET_H
//
在源文件中实现
#include "widget.h"
#include "ui_widget.h"
#include <QString>
Widget::Widget
(
QWidget
*
parent
) :
QWidget
(
parent
),
ui
(
new
Ui::Widget
)
{
ui
->
setupUi
(
this
);
connect
(
ui
->
btn_start
,
&
QPushButton::clicked
,[
this
](){
id
=
startTimer
(
1000
);
});
connect
(
ui
->
btn_stop
,
&
QPushButton::clicked
,[
this
](){
killTimer
(
id
);
});
}
Widget::~Widget
()
{
delete
ui
;
}
void
Widget::timerEvent
(
QTimerEvent
*
e
)
{
static
int
num
=
10
;
num
--
;
ui
->
text_num
->
setText
(
QString::number
(
num
));
}
定时器对象
1,
在头文件中声明定时器对象
2,
在源文件中创建定时器对象
3,
设置定时器的信号与槽
4,
在适当位置启动或停止定时器
相关函数与信号
函数
QTimer(QObject *parent = Q_NULLPTR);
void start(int msec);
参数
:
延迟时间
void start();
void stop();
信号
void timeout(QPrivateSignal);
示例:
//头文件
#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 = 0);
~Widget();
private slots:
void on_btn_start_clicked();
void on_btn_stop_clicked();
private:
Ui::Widget *ui;
QTimer *timer;
public slots:
void setTime();
};
#endif // WIDGET_H
//源文件
#include "widget.h"
#include "ui_widget.h"
#include <QString>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
timer = new QTimer(this);
connect(timer,&QTimer::timeout,this,&Widget::setTime);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_btn_start_clicked()
{
timer->start(1000);
}
void Widget::on_btn_stop_clicked()
{
timer->stop();
}
void Widget::setTime()
{
static int time = 10;
time--;
ui->text_num->setText(QString::number(time));
}
延迟执行
注意
:
只会执行一次
头文件
QTimer
相关函数
void singleShot(int msec, Functor functor)
示例:
QTimer::singleShot(5000,[&](){
qDebug() << "
延迟执行
" << endl;
});