Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >qt tabwidget切换_标签怎么在新窗口打开

qt tabwidget切换_标签怎么在新窗口打开

作者头像
全栈程序员站长
发布于 2022-11-04 07:31:59
发布于 2022-11-04 07:31:59
3.9K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

QTabWidget 用来分页显示 重要函数: 1.void setTabText(int, QString); //设置页面的名字. 2.void setTabToolTip(QString); //设置页面的提示信息. 3.void setTabEnabled(bool); //设置页面是否被激活. 4.void setTabPosition(QTabPosition::South); //设置页面名字的位置. 5.void setTabsClosable(bool); //设置页面关闭按钮。 6.int currentIndex(); //返回当前页面的下标,从0开始. 7.int count(); //返回页面的数量. 8.void clear(); //清空所有页面. 9.void removeTab(int); //删除页面. 10.void setMoveable(bool); //设置页面是否可被拖拽移动. 11.void setCurrentIndex(int); //设置当前显示的页面.

signals: 1.void tabCloseRequested(int). //当点击第参数个选项卡的关闭按钮的时候,发出信号. 2.void tabBarClicked(int). //当点击第参数个选项卡的时候,发出信号. 3.void currentChanged(int). //当改变第参数个选项卡的时候,发出信号. 4.void tabBarDoubleClicked(int). //当双击第参数个选项卡的时候,发出信号. c.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "c.h"
c::c(QWidget *parent)
: QMainWindow(parent)
{ 

ui.setupUi(this);
//连接信号与槽.
connect(ui.insertButton, SIGNAL(clicked()), this, SLOT(addPageSlot()));    connect(ui.removeButton, SIGNAL(clicked()), this, SLOT(removePageSlot()));    connect(ui.dragButton, SIGNAL(clicked()), this, SLOT(dragPageSlot()));
}
c::~c()
{ 

}
void c::addPageSlot()
{ 

//定义一个QWidget.
QWidget *temp = new QWidget;
//在当前页面的后面插入一个新的页面.
ui.tabWidget->insertTab(ui.tabWidget->currentIndex() + 1, temp, QIcon("Icons/2.png"), QString::number(count));    //显示新的页面.
ui.tabWidget->setCurrentIndex(ui.tabWidget->indexOf(temp));
count++;
}
void c::removePageSlot()
{ 

//删除当前的页面.
ui.tabWidget->removeTab(ui.tabWidget->currentIndex());}
void c::dragPageSlot()
{ 

//设置页面项是可被移动的.
ui.tabWidget->setMovable(true);}    

c.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#ifndef C_H
#define C_H
#include <QtWidgets/QMainWindow>
#include "ui_c.h"
#include <QTabWidget>
#include <QPushButton>
class c : public QMainWindow
{
Q_OBJECT
public:
c(QWidget *parent = 0);
~c();
private slots:   
void addPageSlot();    
void removePageSlot();    
void dragPageSlot();private:
Ui::cClass ui;   
int count = 0;
};#endif

QTabWidget添加选项卡的方法可用使用addTab方法和insertTab方法。 1、增加选项卡的addTab方法

addTab用于给QTabWidget增加一个选项卡,选项卡位置在现所有选项卡后面,调用语法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int addTab(QWidget page, str label)
int addTab(QWidget page, QIcon icon, str label)

说明:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
page为一个QWidget 实例对象,其名字为对应选项卡的名字
label为选项卡栏显示的选项卡标题文字,文字中可通过与符号(&)带一个快捷键字母,对应快捷键为:Alt+与符号后面字母
icon为选项卡栏显示的选项卡图标
返回值为新加选项卡在选项卡栏中的位置索引

注意:

如果在QTabWidget所在窗口show()之后调用addTab(),布局系统将尝试调整部件层次结构可能导致闪烁。为了防止这种情况可以在更改之前将窗口的QWidget.updateselebled属性设置为False,在更改完成时将属性设置为True,使部件再次接收绘制事件。 示例代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
	self.tab_reportManner = QtWidgets.QWidget()
self.tab_reportManner.setObjectName("tab_reportManner")
icon.addPixmap(QtGui.QPixmap(":/IT/图像文件/blog.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.tabWidget.addTab(self.tab_reportManner, icon, "疫情上报方式")

2、插入选项卡的insertTab方法

QTabWidget的insertTab方法用于在QTabWidget指定位置插入一个选项卡,调用语法如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
int insertTab(int index, QWidget page, str label)
int insertTab(int index, QWidget page, QIcon icon, str label)

说明:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
insertTab方法的参数除了多了个index参数外,其他参数和返回值都是一样
如果index值超出范围,则新选项卡在所有选项卡最后面
如果在调用此函数之前QTabWidget没有选项卡,则插入选项卡将成为当前页,否则当前页保持不变

Qt–多页面切换组件

一.多页面切换组件 多页面的切换在我们日常的软件使用中是十分广泛的,有着很好的便捷性,下面一张图片展示了多页面的使用的便捷性

可以看到用鼠标点击不同的标题时会出现不同的页面内容

A.Qt中的多页面切换组件QTabWidget

Qt中为多页面切换的实现提供了一个专门的类QTabWidget,它可以实现能够在同一个窗口中自由切换不同页面的内容,并且是一个容器类型的组件,提供友好的页面切换方式,在QTabWidget类中提供了很多在工程中实用的函数,比如设置Tab标签的位置void setTabPosition(TabPosition)(North South West East),设置Tab的外观 void setTabShape(),设置Tab的可关闭模式void setTabsClosable()等各种在实际应用中用的较多的函数,具体的函数可以在Qt助手进行查询。

QTabWidget的使用方式–在Qt中的应用程序中创建QTabWidget的对象,将其他的QWiget对象加入该对象中(在QTabWidget对象中加入一个组件将生成一个新的页面,同时QTabWidget对象每次只能加入一个QWiget对象),但是在实际的使用中每个页面会有多个的子组件,这时应该在工程中创建容器类型的组建对象,将多个子组件在容器对象中布局,最后将容器对象加入QTabWidget中生成新的页面.

1.能够在同一窗口中自由切换不同页面的内容

2.是一个容器类型的组件,同时提供友好的页面切换方式

Qt–多页面切换组件 QTabWidget的使用方式 1.在应用程序中创建QTabWidget的对象 2.将其他QWidget对象加入该对象中

实现过程 1.创建容器类的组件对象 2.将多个子组件在容器对象中布局 3.将容器对象加入QTabWidget中生成新的页面 Qt–多页面切换组件 QTabWidget组件的基本用法 Qt–多页面切换组件

B.QTabWidget组件的高级用法 1.设置Tab标签的位置 2.设置Tab的外观 3.设置Tab的可关闭模式

QTabWidget组件预定义的信号 void currentChange(int index)–当前显示的页面发送变化,index为新页面下标 void tabCloseRequsted(int index)–位置为index页面的关闭按钮被点击发出关闭请求 代码示例 Widget.h

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTableWidget>
class Widget : public QWidget
{
Q_OBJECT
QTabWidget m_tabWidget;
protected slots:
void onTabCurrentChanged(int index);
void onTabCloseRequested(int index);
public:
Widget(QWidget *parent = 0);
~Widget();
};
#endif // WIDGET_H

Widget.cpp

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "Widget.h"
#include <QPlainTextEdit>
#include <QLabel>
#include <QPushButton>
#include <QVBoxLayout>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{ 

//QTabWidget的基本设置
m_tabWidget.setParent(this);
m_tabWidget.move(10, 10);
m_tabWidget.resize(200, 200);
m_tabWidget.setTabPosition(QTabWidget::North);
m_tabWidget.setTabShape(QTabWidget::Triangular);
m_tabWidget.setTabsClosable(false);
QPlainTextEdit* edit = new QPlainTextEdit(&m_tabWidget);
edit->insertPlainText("页面1");
m_tabWidget.addTab(edit, "1st");
QWidget* widget = new QWidget(&m_tabWidget);
QVBoxLayout* layout = new QVBoxLayout();
QLabel* lbl = new QLabel(widget);
QPushButton* btn = new QPushButton(widget);
lbl->setText("页面2");
lbl->setAlignment(Qt::AlignCenter);
btn->setText("页面2");
layout->addWidget(lbl);
layout->addWidget(btn);
widget->setLayout(layout);
m_tabWidget.addTab(widget, "2nd");
m_tabWidget.setCurrentIndex(1);
connect(&m_tabWidget, SIGNAL(currentChanged(int)), this, SLOT(onTabCurrentChanged(int)));
connect(&m_tabWidget, SIGNAL(tabCloseRequested(int)), this, SLOT(onTabCloseRequested(int)));
}
void Widget::onTabCurrentChanged(int index)
{ 

qDebug() << "Page change to: " << index;
}
void Widget::onTabCloseRequested(int index)
{ 

m_tabWidget.removeTab(index);
}
Widget::~Widget()
{ 

}

运行的结果如图所示

QTabWidget实现了双击关闭标签页

重载了QTabWidget(由于tabBar()是protected),这样就可以获取到标签了。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
1 class Tab : public QTabWidget 2 { 

3     Q_OBJECT
4 public:
5     Tab(QWidget *parent = 0);
6     QTabBar* GetBar();
7 protected:
8     void mousePressEvent(QMouseEvent *event);
9 };

然后在实现一个事件过滤器,首先判断事件是双击事件,然后判断是否为标签位置,如果是则删除当前标签页,由于双击事件中必触发单击,即标签页选中事件,因此无需考虑双击其他标签页引起的index变更问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 1 #ifndef MYEVENTFILTER_H
2 #define MYEVENTFILTER_H
3 #include <QMainWindow>
4 #include <QMouseEvent>
5 #include "tab.h"
6 
7 extern int tabindex_current;
8 extern int tabindex_old;
9 extern Tab *tabWidget;
10 extern QPoint tableft;
11 extern int tabwidth;
12 extern int tabheight;
13 
14 //实现双击关闭Tab标签
15 class myEventFilter: public QObject 16 { 

17   public:
18   myEventFilter():QObject()
19   { 
};
20   ~myEventFilter(){ 
};
21 
22   bool eventFilter(QObject* object,QEvent* event)
23   { 

24       if (event->type()==QEvent::MouseButtonDblClick)
25       { 

26           QMouseEvent *e = static_cast<QMouseEvent*>(event);
27           QPoint pos = e->pos();
28           int x1 = tableft.x();
29           int x2 = tableft.x()+tabwidth;
30           int y1 = tableft.y();
31           int y2 = tableft.y()+tabheight;
32           if (pos.x() >= x1 && pos.y() >= y1 && pos.x() <= x2 && pos.y() <= y2)
33               tabWidget->removeTab(tabindex_current);
34       }
35       return QObject::eventFilter(object,event);
36   };
37 };
38 
39 #endif // MYEVENTFILTER_H
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
最后绑定到主函数main中,这样就可捕捉到所有的事件了:
1 qApp->installEventFilter(new myEventFilter());
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
另外,需在标签页切换时更新宽度信息(高度无需更新):
1 void MainWindow::updateBar()
2 { 

3     tabindex_current = tabWidget->currentIndex();
4     tabindex_old = tabindex_current;
5     QTabBar *bar = tabWidget->GetBar();
6     if (bar->size().width() > 0)
7          tabwidth = bar->size().width();
8 }

QTabWidget添加关闭子标签功能

QTabWidget添加关闭子标签功能,QTabWidget 有个属性 tabsClosable ,将其设置为True即可出现关闭按钮。 默认情况下,每个标签上的关闭按钮是没有任何响应的,我们需要自己动手为他添加关闭响应。 关闭信号为 void tabCloseRequested(int index) 关闭函数为 void removeTab(int index) 注意关闭标签的是一个普通公共函数,不是槽函数,不可以直接与信号相连,我们需要自己手动定义个接受 int类型的槽函数,然后把参数再传递给关闭函数。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTabWidget>
#include <QTextEdit>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{ 

ui->setupUi(this);
connect(ui->tabWidget,SIGNAL(tabCloseRequested(int)),this,SLOT(removeSubTab(int)));
}
MainWindow::~MainWindow()
{ 

delete ui;
}
void MainWindow::removeSubTab(int index)
{ 

ui->tabWidget->removeTab(index);
}
void MainWindow::on_pushButton_clicked()
{ 

QTextEdit *edit=new QTextEdit;
ui->tabWidget->addTab(edit,"hitemp 1");
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年9月13日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Angular 从入坑到挖坑 - 路由守卫连连看
Angular 入坑记录的笔记第六篇,介绍 Angular 路由模块中关于路由守卫的相关知识点,了解常用到的路由守卫接口,知道如何通过实现路由守卫接口来实现特定的功能需求,以及实现对于特性模块的惰性加载
程序员宇说
2020/06/04
3.8K0
Angular 路由配置(预加载配置,懒加载配置)
(1)RouterModule对象提供了两个静态的方法:forRoot()和forChild()来配置路由信息。
玖柒的小窝
2021/11/04
3.3K0
angular 路由使用
创建路由模块 ng generate module app-routing --flat --module=app 修改app-routing.module.ts import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; // 引入路由模块 import { Routes, RouterModule } from '@angular/router'; // 引入被路由的组件 import
路过君
2020/06/19
1K0
angular使用NG ZORRO来构建博客展示项目(项目结构及路由)
创建项目 使用angular脚手架搭建项目。 如何使用angular脚手架搭建项目参看这篇文章 ng new blog-angular 安装NG ZORRO 我们界面UI选用NG ZORRO。 可以参考官网,https://ng.ant.design/#/docs/angular/getting-started cd blog-angular npm install ng-zorro-antd --save 在根 module 中需要使用 NgZorroAntdModule.forRoo
易兒善
2018/08/21
1.3K0
angular使用NG ZORRO来构建博客展示项目(项目结构及路由)
了解 Angular 开发的内容
阅读本文,是在你了解 Angular 基本知识的前提下,如果读者还不了解,请前往官网了解。
Jimmy_is_jimmy
2022/04/15
1K0
了解 Angular 开发的内容
模块化开发 Angular 应用 [含懒加载]
然后,我们将学习怎么使用我们的模块来启用延迟加载,从而使应用更小,使用户体验更好。
Jimmy_is_jimmy
2022/09/19
3.1K0
模块化开发 Angular 应用 [含懒加载]
前端路由的原理及应用
早期的路由都是后端来实现的,根据用户访问的地址的不同,浏览器从服务器请求对应的资源或页面展示给用户。当页面数据量大,结构复杂的时候,随之造成服务器的压力也比较大,而且用户访问速度也比较慢。
江米小枣
2020/06/16
2.3K0
前端路由的原理及应用
hash和history的原理和区别
目前单页应用(SPA)越来越成为前端主流,单页应用一大特点就是使用前端路由,由前端来直接控制路由跳转逻辑,而不再由后端人员控制,这给了前端更多的自由。
前端小tips
2021/11/23
2K0
hash和history的原理和区别
Angular 2 + 折腾记 :(4)初步了解路由及使用
路由就是控制视图与视图之间的跳转,之间还可以传递参数什么的,路由的退后及前进不会完整的请求整个页面,还可以完全不请求(在生命周期里面控制);
CRPER
2018/08/28
3.1K0
ionic4初级教程-含登录、访问权限验证功能
如果第一次安装的时候失败,没关系 删掉已经生成的ioinc4Learn文件包,重新运行命令
lilugirl
2019/05/28
2.5K0
ionic4初级教程-含登录、访问权限验证功能
你好,谈谈你对前端路由的理解
作者:尼克陈 https://juejin.cn/post/6917523941435113486
用户4456933
2021/06/01
1K0
你好,谈谈你对前端路由的理解
一文搞懂前端路由的原理(Vue、React、Angular)
前端三大框架 Angular、React、Vue ,它们的路由解决方案 angular/router、react-router、vue-router 都是基于前端路由原理进行封装实现的,因此将前端路由原理进行了解和掌握是很有必要的,因为我们再使用的过程中也难免会遇到一些坑,一旦我们掌握了它的实现原理,那么就能在开发中对路由的使用更加游刃有余。
前端老道
2022/03/29
1.3K0
一文搞懂前端路由的原理(Vue、React、Angular)
彻底理清前端单页面应用(SPA)的实现原理
传统的多页面应用构建方式: 纯服务端渲染,前后端不分离,使用jsp,jade,'ejs','tempalte'等技术在后台先拼接成对应的HTML结构,然后转换成字符串,在每个对应的路由返回对应的数据(文件)即可 Jade模版服务端渲染,代码实现: const express= require('express') const app =express() const jade = require('jade') const result = *** const url path = *** const
Peter谭金杰
2019/08/02
3.2K2
前端路由跳转基本原理
目前前端三杰 Angular、React、Vue 都推介单页面应用 SPA 开发模式,在路由切换时替换 DOM Tree 中最小修改的部分 DOM,来减少原先因为多页应用的页面跳转带来的巨量性能损耗。它们都有自己的典型路由解决方案,@angular/router、react-router、vue-router。
前端下午茶
2019/06/27
1.7K0
前端路由跳转基本原理
前端路由相关实现
版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://blog.csdn.net/wkyseo/article/details/55255056
空空云
2018/09/27
5860
前端路由相关实现
前端路由那些事
假设你浏览器访问的url地址是 http://127.0.0.1/#/test 那么通过 location.hash 获取的hash值为 #/test
树酱
2020/07/03
1K0
前端路由那些事
hash和history路由模式
前端路由是指在浏览器端控制页面内容切换显示的机制。在没有服务器端参与的情况下,前端路由可以根据URL的变化,对应展现不同的内容,实现页面的“伪”跳转。
y191024
2024/01/29
2580
hash和history路由模式
Angular 启用预加载
在使用路由延迟加载中,我们介绍了如何使用模块来拆分应用,在访问到这个模块的时候, Angular 加载这个模块。但这需要一点时间。在用户第一次点击的时候,会有一点延迟。
玖柒的小窝
2021/11/03
1.6K0
Angular 启用预加载
再谈location与history之跳转转态监控—router的两种实现模式
使用location对象可以通过很多方式来改变浏览器的位置,每次修改location的属性(hash除外),页面都会以新URL重新加载。
周陆军博客
2023/05/07
2.5K0
前端开发:vue路由之前端路由的原理
现在mvvm框架已经火的不成样了,React、Angular和Vue.js的发布让前端工程化成为主流,大前端时代已经到来了,最近接触了vue的前端路由,闲来无事就开始琢磨源码,下面来说说前端路由的原理。
用户5827212
2019/08/07
1K0
推荐阅读
相关推荐
Angular 从入坑到挖坑 - 路由守卫连连看
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验