1. 常用控件
Input Widgets:
- Line Edit:单行文本输入
- 设置文本:
setText()
,ui->lineEdit->setText("654321");
- 获取文本:
text()
,QString str = ui->lineEdit->text(); //获取内容
- 设置文本:
- Text Edit:可显示文本和图片
- Plain Text Edit:只能显示文本
Display Widgets:
- Label:可显示文字、图片、动画、网址等等
- LCD Number:数码管
- Progress Bar:进度条
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QStringList>
#include <QCompleter>
#include <QMovie>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//获取内容
QString str = ui->lineEdit->text();
qDebug() << str ;
//设置内容
ui->lineEdit->setText("654321");
//设置内容显示间隙
ui->lineEdit->setTextMargins(15,0,0,0);
//设置内容显示方式
// ui->lineEdit->setEchoMode(QLineEdit::Password);
// 内容提示框
QStringList list;
list << "Hello" << "how are you" << "test";
QCompleter *com = new QCompleter(list,this);
com->setCaseSensitivity(Qt::CaseInsensitive);
ui->lineEdit->setCompleter(com);
//QLabel
//设置文本内容
ui->labelText->setText("^_^");
//设置图片
ui->labelImage->setPixmap(QPixmap("://Image/image2.png"));
//让图片自动适应大小
ui->labelImage->setScaledContents(true);
//创建动画
QMovie *myMovie = new QMovie("://Image/dog.gif");
//设置动画
ui->labelGif->setMovie(myMovie);
//启动动画
myMovie->start();
ui->labelGif->setScaledContents(true);
//设置html
ui->labelUrl->setText("<h1><a href=\"www.baidu.com\">百度一下</a></h1>");
ui->labelUrl->setOpenExternalLinks(true);
//数码控
ui->lcdNumber->display(123);
//进度条
ui->progressBar->setMinimum(0);//最小值
ui->progressBar->setMaximum(100);//最大值
ui->progressBar->setValue(15);//当前值
}
MainWindow::~MainWindow()
{
delete ui;
}
2. 布局
- 水平布局
- 垂直布局
- 网格布局
3. 自定义控件
写完控件后,在容器上右击Promote to
smallwidget.cpp
#include "smallwidget.h"
#include <QSpinBox>
#include <QSlider>
#include <QHBoxLayout>
smallwidget::smallwidget(QWidget *parent) : QWidget(parent)
{
QSpinBox *spin = new QSpinBox(this);
QSlider *slider = new QSlider(Qt::Horizontal,this);//水平布局
// 把控件添加到布局中
QHBoxLayout *hLayout = new QHBoxLayout(this);
hLayout->addWidget(spin);
hLayout->addWidget(slider);
//setLayout(hLayout)
connect(spin,static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
slider,&QSlider::setValue);
connect(slider,&QSlider::valueChanged,spin,&QSpinBox::setValue);
}
4. Qt样式表
Qt样式表与CSS语法规则几乎完全相同
5.事件
事件
鼠标事件、键盘事件、定时器事件:
以标签显示为例
注意:Qt中少包含头文件
<QTimerEvent>
,编译器也没报错,但是实际定时器事件没有响应。不知是版本问题还是BUG
事件的接收和忽略
event()函数
主要做事件分发
事件过滤器
注意,事件过滤器和被安装过滤器的组件必须在同一线程,否则过滤器将不起作用。另外,如果在安装过滤器之后,这两个组件到了不同的线程,那么只有等到二者重新回到同一线程时过滤器才会有效。
mylabel.h
#ifndef MYLabel_H
#define MYLabel_H
#include <QLabel>
class myLabel : public QLabel
{
Q_OBJECT
public:
explicit myLabel(QWidget *parent = nullptr);
protected:
//鼠标点击事件
void mousePressEvent(QMouseEvent *ev);
//鼠标释放事件
void mouseReleaseEvent(QMouseEvent *ev);
//鼠标移动事件
void mouseMoveEvent(QMouseEvent *ev);
//进入窗口区域
void enterEvent(QEvent *);
//离开窗口区域
void leaveEvent(QEvent *);
signals:
public slots:
};
#endif // MYLabel_H
mylabel.cpp
#include "mylabel.h"
#include <QMouseEvent>
#include <QDebug>
myLabel::myLabel(QWidget *parent) : QLabel(parent)
{
//要想一进界面就有效
this->setMouseTracking(true);
}
void myLabel::mousePressEvent(QMouseEvent *ev)
{
int i = ev->x();
int j = ev->y();
//sprinf
/*
* QString str = QString("abc %1 ^_^ %2").arg(123).arg("mike");
* str = abc 123 ^_^ mike
*/
if(ev->button() == Qt::LeftButton)
{
qDebug() << "鼠标左键被按下!";
}else if(ev->button() == Qt::RightButton)
{
qDebug() << "鼠标右键被按下!";
}else if(ev->button() == Qt::MidButton)
{
qDebug() << "鼠标中键被按下!";
}
// 可嵌入html语句
QString text = QString("<h1>Mouse Press:(%1,%2)</h1>")
.arg(i).arg(j);
this->setText(text);
}
void myLabel::mouseReleaseEvent(QMouseEvent *ev)
{
QString text = QString("<h1>Mouse Release:(%1,%2)</h1>")
.arg(ev->x()).arg(ev->y());
this->setText(text);
}
void myLabel::mouseMoveEvent(QMouseEvent *ev)
{
QString text = QString("<h1>Mouse Move:(%1,%2)</h1>")
.arg(ev->x()).arg(ev->y());
//this->setText(text);
}
void myLabel::enterEvent(QEvent *e)
{
QString text = QString("<center><h1>Mouse enter</h1></center>");
this->setText(text);
}
void myLabel::leaveEvent(QEvent *e)
{
QString text = QString("<center><h1>Mouse leave</h1></center>");
this->setText(text);
}
mybutton.h
#ifndef MYBUTTON_H
#define MYBUTTON_H
#include <QPushButton>
class myButton : public QPushButton
{
Q_OBJECT
public:
explicit myButton(QWidget *parent = nullptr);
protected:
void mousePressEvent(QMouseEvent *e);
signals:
public slots:
};
#endif // MYBUTTON_H
mybutton.cpp
#include "mybutton.h"
#include <QMouseEvent>
#include <QDebug>
myButton::myButton(QWidget *parent) : QPushButton(parent)
{
}
void myButton::mousePressEvent(QMouseEvent *e)
{
if(e->button() == Qt::LeftButton)
{
//如果是左键按下
qDebug()<<"按下的是左键";
}
else {
//不作处理
//QPushButton::mousePressEvent(e);
//如果把语句放在这儿,而没有后面那句,
//信号被忽略以后便不会继续往下传,因此clicked信号
//就不会被触发,其所对应的槽函数当然也不会被执行
//这种问题务必要注意,可以重写自己的事件,
//但执行完后务必保证信号会继续往下传,否则会导致
//后续信号无法继续接收,这种BUG很难找出来!!
}
//信号忽略,继续往下传
QPushButton::mousePressEvent(e);
}
mywidget.h
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QWidget>
namespace Ui {
class myWidget;
}
class myWidget : public QWidget
{
Q_OBJECT
public:
explicit myWidget(QWidget *parent = nullptr);
~myWidget();
protected:
//键盘按下事件
void keyPressEvent(QKeyEvent *);
//定时器事件
void timerEvent(QTimerEvent *);
//关闭事件
void closeEvent(QCloseEvent *);
//重写event事件
bool event(QEvent *);
//事件过滤器
bool eventFilter(QObject *,QEvent *);
private:
Ui::myWidget *ui;
int timerID;
int timerID2;
};
#endif // MYWIDGET_H
mywidget.cpp
#include "mywidget.h"
#include "ui_mywidget.h"
#include <QDebug>
#include <QKeyEvent>
#include <QTimerEvent>
#include <QCloseEvent>
#include <QMessageBox>
#include <QEvent>
myWidget::myWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::myWidget)
{
ui->setupUi(this);
//启动定时器
timerID = this->startTimer(1000);//毫秒为单位,每隔1s触发一次定时器
this->timerID2 = this->startTimer(500);
connect(ui->pushButton,&myButton::clicked,
[=]()
{
qDebug() <<"clicked 按钮被按下";
});
//安装过滤器
ui->label_2->installEventFilter(this);
}
myWidget::~myWidget()
{
delete ui;
}
void myWidget::keyPressEvent(QKeyEvent *e)
{
qDebug() << (char)e->key();
if(e->key() == Qt::Key_A)
{
qDebug() << "Qt::Key_A";
}
}
void myWidget::timerEvent(QTimerEvent *e)
{
if(e->timerId() == this->timerID)
{
static int sec = 0;
ui->label_3->setText(QString("<center><h1>timer1 out: %1</h1></center>").arg(sec++));
if(5 == sec)
{
//停止定时器
this->killTimer(this->timerID);
}
}else if (e->timerId() == this->timerID2)
{
static int sec2 = 0;
ui->label_2->setText(
QString("<center><h1>timer2 out: %1</h1></center>").arg(sec2++)
);
}
}
void myWidget::closeEvent(QCloseEvent *e)
{
int ret = QMessageBox::question(this,"question","是否关闭窗口");
if(ret == QMessageBox::Yes)
{
//关闭窗口
//处理关闭窗口事件,接收事件,事件就不会再往下传递
e->accept();
}
else {
//不关闭窗口
//忽略事件,事件继续给父组件传递
e->ignore();
}
}
bool myWidget::event(QEvent *e)//不要轻易改此函数
{
//事件分发
// switch (e->type()) {
// case QEvent::Close:
// closeEvent(e);
// break;
// case QEvent::MouseMove:
// mouseMoveEvent(e);
// break;
if(e->type() == QEvent::Timer)
{
//干掉计时器
//如果返回true,事件停止传播
QTimerEvent *env = static_cast<QTimerEvent *>(e);
timerEvent(env);
return true;
}
else if (e->type() == QEvent::KeyPress) {
QKeyEvent *env = static_cast<QKeyEvent *>(e);
if(env->key() == Qt::Key_B)
{
return QWidget::event(e);
}
return true;
}
else {
return QWidget::event(e);
}
}
bool myWidget::eventFilter(QObject *obj, QEvent *e)
{
if(obj == ui->label_2)
{
QMouseEvent *env = static_cast<QMouseEvent *>(e);
//判断事件
if(e->type() == QEvent::MouseMove)
{
ui->label_2->setText(QString("Mouse move:(%1,%2)").
arg(env->x()).arg(env->y()));
return true;
}
else {
return QWidget::eventFilter(obj,e);
}
}
return QWidget::eventFilter(obj,e);
}
Qt复合快捷键
QString s="";
switch(e->modifiers()){
case Qt::ControlModifier:
s = "Ctrl+";
break;
case Qt::AltModifier:
s = "Alt+";
break;
}
switch(e->key())
{
case Qt::Key_Left:
s += "Left_Key Press";
break;
case ...
}
总结
- 控件
- 按钮类:QPushButton、QToolButton、QRadioButton
- item:QListWidget
- 容器类:QStackWidget、QWidget、QFrame、
- 编辑类:QComboBox、QLineEdit、QTextEdit
- 显示类:QLabel、QLCDNumber、QProgressBar
- 布局
- 水平
- 垂直
- 网格
- 布局属性
- 大小策略
- 最小大小
- 最大大小
- 容器(分类)
- 弹簧
- 自定义控件(提升)
- ui的控件和自定义控件的父类(基类)要一致
- 选中ui控件-> 提升
- 常用事件处理
- 事件处理器
- 都是虚函数(基类中定义QWidget QObject)
- 我们派生类(子类)