我使用QTabWidget
我需要一种方法来处理当前标签实际发生之前的更改,如果满足某些条件,可能会取消它。在当前选项卡发生更改后收到QTabWidget::currentChanged
信号,但是是否有QTabWidget::currentChanging
信号或其他方式来实现我需要的行为?
答案 0 :(得分:5)
在我的情况下,我像这样连接SIGNAL和SLOT:
//check if user clicked at a tab
connect(ui->tabWidget, SIGNAL(currentChanged(int)), this, SLOT(tabSelected()));
并在tabSelected()
函数中,我查看当前的标签索引:
void MainWindow::tabSelected(){
if(ui->tabWidget->currentIndex()==0){
// Do something here when user clicked at tab1
}
if(ui->tabWidget->currentIndex()==3){
// Do something here when user clicked at tab4
}
}
答案 1 :(得分:3)
这就是我解决它的方式
void MainWindow::on_tabWidget_currentChanged(int index)
{
if (lockTabs) ui->tabWidget->setCurrentIndex(lockedTab);
}
单击按钮,我将lockTabs设置为true并将当前选项卡索引保存为lockedTab(int)。无论你点击什么标签,它都会让你回到锁定标签。
我同意第一条评论,禁用标签是更好的方式。这是我禁用标签的解决方案:
void MainWindow::lockTabs(int except){
for (int i=0; i<ui->tabWidget->count(); i++) {
if (i!=except) ui->tabWidget->setTabEnabled(i, false);
}
}
void MainWindow::unlockTabs() {
for (int i=0; i<ui->tabWidget->count(); i++) {
ui->tabWidget->setTabEnabled(i, true);
}
}
答案 2 :(得分:1)
在标题中,声明:
tabChanged
创建一个例程currentChanged()
,其中包含void pkgName::tabChanged
//"ask your question"
if "bad reply"
// This is where you'll "set back to your old tab"
ui->tabWidget->setCurrentWidget(savedWidget)
end if
savedWidget = ui->tabWidget-> getCurrentWidget()
// Process
信号的插槽。然后:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>caro homepage</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<style type="text/css">
.carousel-inner{
width:auto;
height:200px;
max-height:200px !important;
}
.carousel-content {
color:black;
display:flex;
text-align:center;
}
</style>
</head>
<body>
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="4000" data-pause="hover" >
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
<li data-target="#myCarousel" data-slide-to="1"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner" role="listbox">
<div class="item active">
<div class="carousel-content">
<div style="text-align:center">
<h3>#1</h3>
<p>The first Message.</p>
</div>
</div>
</div>
<div class="item">
<div class="carousel-content">
<div style="text-align:center">
<h3>#2</h3>
<p>The 2nd Message.</p>
</div>
</div>
</div>
</div>
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</body>
</html>
答案 3 :(得分:0)
如果禁止更改,则使用常规的QTabWidget
并在发出currentChanged
之后切换回上一个选项卡对用户而言并不适合,因为在重新选择上一个选项卡之前新的选项卡已可见,这是由于QTabWidget
通知标签“已更改”,而不是“即将更改”。
一种选择是创建自己的QTabWidget
。感谢QTabBar
,这很明显。
您还需要创建类似于QTabWidget
的{{1}}函数,但并不需要那么多函数。
下面是一个类似QTabWidget
的类的示例,其中发出了QTabWidget
信号,通知该标签即将更改,可以将aboutToChangeTab
设置为allowed
以禁止标签更改。
false
并且:
#pragma once
#include <QWidget>
class QTabBar;
class QStackedWidget;
class SmartTabWidget : public QWidget
{
Q_OBJECT
typedef QWidget baseClass;
public:
SmartTabWidget( QWidget* parent );
int addTab(QWidget* page, const QString& label);
int addTab(QWidget* page, const QIcon& icon, const QString& label);
int currentIndex() const;
QWidget* widget( int index );
signals:
void aboutToChangeTab( QWidget* curTab, QWidget* nextTab, bool* allowed );
private slots:
void tryToChangeTab( int index );
private:
QTabBar* m_tab;
QStackedWidget* m_stack;
};
一个人可以将#include "smart_tab_widget.h"
#include <QTabBar>
#include <QStackedWidget>
#include <QVBoxLayout>
#include <QIcon>
SmartTabWidget::SmartTabWidget( QWidget* widget ) :
baseClass( widget )
{
new QVBoxLayout( this );
layout()->setContentsMargins( 0,0,0,0 );
layout()->addWidget( m_tab = new QTabBar(this) );
layout()->addWidget( m_stack = new QStackedWidget(this) );
connect(m_tab, SIGNAL(currentChanged(int)), this, SLOT(tryToChangeTab(int)));
}
int SmartTabWidget::addTab(QWidget* page, const QString& label)
{
return addTab( page, QIcon(), label );
}
int SmartTabWidget::addTab(QWidget* page, const QIcon& icon, const QString & label)
{
m_stack->addWidget( page );
int index = m_tab->addTab( icon, label );
assert( m_stack->count() == index+1 );
return index;
}
int SmartTabWidget::currentIndex() const
{
return m_tab->currentIndex();
}
QWidget* SmartTabWidget::widget( int index )
{
return m_stack->widget( index );
}
void SmartTabWidget::tryToChangeTab( int index )
{
int currentIndex = m_stack->currentIndex();
bool canChange = true;
emit aboutToChangeTab( m_stack->widget( currentIndex ),
m_stack->widget( index ),
&canChange );
if ( canChange )
{
m_stack->setCurrentIndex( index );
}
else
{
// prevent this function to be called again
bool blocked = m_tab->blockSignals( true );
// unselect requested tab as change is not allowed
m_tab->setCurrentIndex( currentIndex );
m_tab->blockSignals( blocked );
}
}
连接到插槽(aboutToChangeTab
)上,然后执行以下操作:
allowTabChange
答案 4 :(得分:0)
有一个简单的解决方案,它不需要继承 QTabWidget 的事件过滤器。就我而言,我需要禁用切换到特定选项卡
ui->tabWidget->tabBar()->installEventFilter(this);
然后:
bool MainWindow::eventFilter(QObject* watched, QEvent* event)
{
if(watched == ui->tabWidget->tabBar())
{
if(event->type() == QEvent::MouseButtonPress)// || event->type() == QEvent::MouseButtonRelease)
{
auto pos = dynamic_cast<QMouseEvent*>(event)->pos();
auto index = ui->tabWidget->tabBar()->tabAt(pos);
if(ui->tabWidget->widget(index) == ui->addButtonTab)
return true; // cancell event
}
}
return QMainWindow::eventFilter(watched, event);
}
在鼠标点击阶段,可以检索当前选定选项卡的索引并准备切换(或取消切换,如我的示例中所做的那样)。