【Qt】桌面应用开发教程——布局 按钮组 容器 常用控件 消息事件机制_qt 如何按钮切换容器(1)

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

多个可选按键,相当于多个push Button组合在一起

image-20221027181724815

image-20221027182147635

5、项目构建组

  • List widget

有序列表(ui界面操作)

image-20221027184032027
代码

  ui->setupUi(this);
    QListWidgetItem *item = new QListWidgetItem("床前明月光");
	QListWidgetItem *item = new QListWidgetItem("疑是地上霜");
    item->setTextAlignment(Qt::AlignHCenter);
    ui->listWidget->addItem(item);

使用方式 addItem 或者 addItems

QStringList -> std::liststd::string
//使用左移操作符添加成员
QStringList list;
list<<“床前明月光”<<“疑似地上霜”<<“举头望明月”<<“低头思故乡”;

  • treeWidget

树形项目

 //使用treeWidget
    //1 设置标题
    ui->treeWidget->setHeaderLabels(QStringList()<<"英雄"<<"简介");
    //2 添加根节点
    QTreeWidgetItem *liliangItem = new QTreeWidgetItem(QStringList()<<"力量");
    QTreeWidgetItem *minjieItem = new QTreeWidgetItem(QStringList()<<"敏捷");
    QTreeWidgetItem *zhiliItem = new QTreeWidgetItem(QStringList()<<"智力");
    ui->treeWidget->addTopLevelItem(liliangItem);
    ui->treeWidget->addTopLevelItem(minjieItem);
    ui->treeWidget->addTopLevelItem(zhiliItem);
    //3 添加相应的子节点
    QStringList heroL1,heroL2,heroM1,heroM2,heroZ1,heroZ2;
    heroL1 << "刚背猪" << "前排坦克,能在吸收伤害的同时造成可观的范围输出";
    heroL2 << "船长" << "前排坦克,能肉能输出能控场的全能英雄";

    heroM1 << "月骑" << "中排物理输出,可以使用分裂利刃攻击多个目标";
    heroM2 << "小鱼人" << "前排战士,擅长偷取敌人的属性来增强自身战力";

    heroZ1 << "死灵法师" << "前排法师坦克,魔法抗性较高,拥有治疗技能";
    heroZ2 << "巫医" << "后排辅助法师,可以使用奇特的巫术诅咒敌人与治疗队友";
    liliangItem->addChild(new QTreeWidgetItem(heroL1));
    liliangItem->addChild(new QTreeWidgetItem(heroL2));
    minjieItem->addChild(new QTreeWidgetItem(heroM1));
    minjieItem->addChild(new QTreeWidgetItem(heroM2));
    zhiliItem->addChild(new QTreeWidgetItem(heroZ1));
    zhiliItem->addChild(new QTreeWidgetItem(heroZ2));

image-20221027194440395
使用方式
1 设置标题,会根据setHeaderLabels 里边的成员数自己生成有多少列
2 添加根节点 treeWidget->addTopLevelItem
3 根节点下边添加子节点 item->addChild

  • tableWidgeet

表格项目

1 设置行数、列数 setRowCount setColumnCount
2 设置水平的标题 setHorizontalLabels
3 设置表格某行某列的数据 setItem(row,col,item)

//1 设置行数、列数
    ui->tableWidget->setRowCount(5);
    ui->tableWidget->setColumnCount(3);

image-20221027195926676

 //2 设置标题
    ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"英雄"<<"性别"<<"年龄");
    //3 添加数据
    QStringList heroNames = QStringList()<<"亚瑟"<<"妲己"<<"安其拉"<<"赵云"<<"孙悟空";
    QStringList heroGenders = QStringList()<<"男"<<"女"<<"女"<<"男"<<"雄性";
    for(int row =0 ;row <5 ; ++row)
    {
        ui->tableWidget->setItem(row,0,new QTableWidgetItem(heroNames[row]));
        ui->tableWidget->setItem(row,1,new QTableWidgetItem(heroGenders[row]));
        ui->tableWidget->setItem(row,2,new QTableWidgetItem(QString::number(row + 18)));
    }

image-20221027200104914

6、容器

效果:

动画23

tacked Widget 页面切换需要我们自己去实现,一般使用按钮点击的时候切换
setCurrentIndex 方式切换到第几页,序号从0开始

7、常用控件

Qt为我们应用程序界面开发提供的一系列的控件,下面我们介绍两种最常用一些控件,所有控件的使用方法我们都可以通过帮助文档获取。

7.1 QLabel控件使用

QLabel是我们最常用的控件之一,其功能很强大,我们可以用来显示文本,图片和动画等。

7.1.1 显示文字 (普通文本、html)

通过QLabel类的setText函数设置显示的内容:

void setText(const QString &)

  • 可以显示普通文本字符串
QLable *label = new QLable;
label->setText(“Hello, World!”);

  • 可以显示HTML格式的字符串

比如显示一个链接:

QLabel * label = new QLabel(this);
label ->setText("Hello, World");
label ->setText("<h1><a href=\"https://www.baidu.com\">百度一下</a></h1>");
label ->setOpenExternalLinks(true);

其中setOpenExternalLinks()函数是用来设置用户点击链接之后是否自动打开链接,如果参数指定为true则会自动打开。

7.1.2 显示图片

可以使用QLabel的成员函数setPixmap设置图片

void setPixmap(const QPixmap &)

首先定义QPixmap对象

QPixmap pixmap;

然后加载图片

pixmap.load(“:/Image/boat.jpg”);

最后将图片设置到QLabel中

QLabel *label = new QLabel;

label.setPixmap(pixmap);

7.1.3 显示动画

可以使用QLabel 的成员函数setMovie加载动画,可以播放gif格式的文件

void setMovie(QMovie * movie)

首先定义QMovied对象,并初始化:

QMovie *movie = new QMovie(“:/Mario.gif”);

播放加载的动画:

movie->start();

将动画设置到QLabel中:

QLabel *label = new QLabel;

label->setMovie(movie);

7.2 QLineEdit

Qt提供的单行文本编辑框。

7.2.1 设置/获取内容

获取编辑框内容使用text(),函数声明如下:

QString   text() const

设置编辑框内容

void setText(const QString &)

7.2.2 设置显示模式

使用QLineEdit类的setEchoMode () 函数设置文本的显示模式,函数声明:

void setEchoMode(EchoMode mode)

EchoMode是一个枚举类型,一共定义了四种显示模式:

QLineEdit::Normal 模式显示方式,按照输入的内容显示。

QLineEdit::NoEcho 不显示任何内容,此模式下无法看到用户的输入。

QLineEdit::Password 密码模式,输入的字符会根据平台转换为特殊字符。

QLineEdit::PasswordEchoOnEdit 编辑时显示字符否则显示字符作为密码。

另外,我们再使用QLineEdit显示文本的时候,希望在左侧留出一段空白的区域,那么,就可以使用QLineEdit给我们提供的setTextMargins函数:

void setTextMargins(int left, int top, int right, int bottom)

用此函数可以指定显示的文本与输入框上下左右边界的间隔的像素数。

7.3 自定义控件

在搭建Qt窗口界面的时候,在一个项目中很多窗口,或者是窗口中的某个模块会被经常性的重复使用。一般遇到这种情况我们都会将这个窗口或者模块拿出来做成一个独立的窗口类,以备以后重复使用。

在使用Qt的ui文件搭建界面的时候,工具栏栏中只为我们提供了标准的窗口控件,如果我们想使用自定义控件怎么办?

例如:我们从QWidget派生出一个类SmallWidget,实现了一个自定窗口,

// smallwidget.h
class SmallWidget : public QWidget

{
  Q_OBJECT

public:

  explicit SmallWidget(QWidget *parent = 0);

signals:

public slots:

private:

  QSpinBox* spin;

  QSlider* slider;

};

// smallwidget.cpp
SmallWidget::**SmallWidget**(QWidget *parent) : QWidget(parent)

{
  spin = new QSpinBox(this);
  slider = new QSlider(Qt::Horizontal, this);

  // 创建布局对象
  QHBoxLayout* layout = new QHBoxLayout;
  // 将控件添加到布局中
  layout->addWidget(spin);
  layout->addWidget(slider);
  // 将布局设置到窗口中
  setLayout(layout);

  // 添加消息响应
  connect(spin, 
      static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),
     slider, &QSlider::setValue);
  connect(slider, &QSlider::valueChanged, 
      spin, &QSpinBox::setValue);

}

img

那么这个SmallWidget可以作为独立的窗口显示,也可以作为一个控件来使用:

打开Qt的.ui文件,因为SmallWidget是派生自Qwidget类,所以需要在ui文件中先放入一个QWidget控件, 然后再上边鼠标右键

img

弹出提升窗口部件对话框

img

添加要提升的类的名字,然后选择 添加

img

添加之后,类名会显示到上边的列表框中,然后单击提升按钮,完成操作.

我们可以看到, 这个窗口对应的类从原来的QWidget变成了SmallWidget

img

再次运行程序,这个widget_3中就能显示出我们自定义的窗口了.

8、消息事件机制

8.1 事件

事件(event)是由系统或者 Qt 应用程序本身在不同的时刻发出的。当用户按下鼠标、敲下键盘,或者是窗口需要重新绘制的时候,都会发出一个相应的事件。一些事件在对用户操作做出响应时发出,如键盘事件等;另一些事件则是由系统自动发出,如计时器事件。01_事件分发

8.2 事件处理函数

在所有组件的父类QWidget中,定义了很多事件处理的函数,如

-  keyPressEvent():键盘按键按下事件
-  keyReleaseEvent():键盘按键松开事件
-  mouseDoubleClickEvent():鼠标双击事件
-  mouseMoveEvent():鼠标移动事件
-  mousePressEvent():鼠标按键按下事件
-  mouseReleaseEvent() :鼠标按键松开事件

这些函数都是 protected virtual 的,也就是说,我们可以在子类中重新实现这些函数。下面来看一个例子:

我们先设置ui文件,给一个label控件,并设置带边框属性

image-20221031085046388

然后再新建个c++文件Mylabel重写label,再回去把ui文件的label对象类提升为Mylabel

按键处理函数代码:

protected:
    //重写鼠标按键处理函数
    void mousePressEvent(QMouseEvent *ev);

void Mylabel::mousePressEvent(QMouseEvent *ev)
{
    //输出鼠标事件一些信息
    //获取坐标
    int x = ev->x();
    int y = ev->y();
    //Qstring("%d,%d",x,y);
    QString str = QString("[%1,%2]").arg(x).arg(y) ;
    this->setText(str);
}

image-20221031093938101
效果已经出来了,样式需要完善,label是可以使用html语言的,比如居中(center)、标题(h1)、链接等;

我们在来添加获取鼠标按键

 //获取鼠标按键
    Qt::MouseButton btn = ev->button();
    QString strButton = "";
    if(btn == Qt::LeftButton)
    {
           strButton = "LeftButton"  ;
    }
    if(btn == Qt::RightButton)
    {
           strButton = "RightButton"  ;
    }
    if(btn == Qt::MidButton)
    {
           strButton = "MidButton"  ;
    }
 QString str = QString("<h1><center>[%1,%2,%3]</center></h1>").arg(x).arg(y).arg(strButton) ;

EventLabel继承了QLabel,覆盖了mousePressEvent()、mouseMoveEvent()和MouseReleaseEvent()三个函数。我们并没有添加什么功能,只是在鼠标按下(press)、鼠标移动(move)和鼠标释放(release)的时候,把当前鼠标的坐标值显示在这个Label上面。由于QLabel是支持 HTML 代码的,因此我们直接使用了 HTML 代码来格式化文字。

QString的arg()函数可以自动替换掉QString中出现的占位符。其占位符以 % 开始,后面是占位符的位置,例如 %1,%2 这种。

QString(“[%1, %2]”).arg(x).arg(y);

语句将会使用x替换 %1,y替换 %2,因此,生成的QString为[x, y]。

image-20221031095435159
鼠标移动函数代码:

 //重写鼠标移动的处理函数
    void mouseMoveEvent(QMouseEvent *ev) ;

我们把上面的鼠标按键定义代码Ctrl+v下来,运行之后,发现有问题,首先我们按动鼠标移动,没有显示是左键还是右键,这是因为,函数是根据位操作进行识别的,我们需要使用位判断,这里就不能是==,还有长按移动鼠标是一个连续的动作,不再是单击按键,这里也是需要使用另一个按键Buttons有个s,也是按位或

image-20221031100536151

 Qt::MouseButtons btns = ev->buttons();
QString strButton = "";
    if(btns & Qt::LeftButton)
    {
           strButton = "LeftButton"  ;
    }

从mouseButton->改为mouseButtons,button->改为buttons,==->改为&

为了可以同时按多个按键,可以使用+=

if(btns & Qt::LeftButton)
    {
           strButton += "LeftButton"  ;
    }

并且为了分清楚是按键还是移动,添加打印信息,如果是按键打印press和如果是移动鼠标就打印move

动画24

为什么要点击鼠标之后才能在mouseMoveEvent()函数中显示鼠标坐标值?

这是因为QWidget中有一个mouseTracking属性,该属性用于设置是否追踪鼠标。只有鼠标被追踪时,mouseMoveEvent()才会发出。如果mouseTracking是 false(默认即是),组件在至少一次鼠标点击之后,才能够被追踪,也就是能够发出mouseMoveEvent()事件。如果mouseTracking为 true,则mouseMoveEvent()直接可以被发出。

 this->setMouseTracking(true);

8.3 事件分发函数event

事件对象创建完毕后,Qt 将这个事件对象传递给QObject的event()函数。event()函数并不直接处理事件,而是将这些事件对象按照它们不同的类型,分发给不同的事件处理器(event handler)。

 bool event(QEvent *e);

如上所述,event()函数主要用于事件的分发。所以,如果你希望在事件分发之前做一些操作,就可以重写这个event()函数了。

事件先会到达窗口的event函数 , event函数 返回值:true表示该事件得到处理,如果是false,没被处理,事件会继续传递到父窗口

if(e->type()==QEvent::MouseMove)
{
	this->mouseMoveEvent(static_cast<QMouseEvent *>(e));//强转
	return true;
}

其他没有被处理的事件,就使用父类的eventreturn QLabel::event(e);

bool Mylabel::event(QEvent *e)
{
    if(e->type()==QEvent::MouseMove)
    {
        //注释了下面一行,将不再触发鼠标移动事件
      this->mouseMoveEvent(static_cast<QMouseEvent*>(e) );
        return true;
    }
    return QLabel::event(e);
}

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

nt *>(e));//强转
return true;
}


其他没有被处理的事件,就使用父类的event`return QLabel::event(e);`



bool Mylabel::event(QEvent e)
{
if(e->type()==QEvent::MouseMove)
{
//注释了下面一行,将不再触发鼠标移动事件
this->mouseMoveEvent(static_cast<QMouseEvent
>(e) );
return true;
}
return QLabel::event(e);
}




[外链图片转存中...(img-M9oKzGls-1715690416801)]
[外链图片转存中...(img-z7CnnwGT-1715690416805)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

  • 20
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值