如何识别当前标签在QTabWidget中的变化?

时间:2011-11-29 09:40:39

标签: qt tabs qtabwidget

我使用QTabWidget我需要一种方法来处理当前标签实际发生之前的更改,如果满足某些条件,可能会取消它。在当前选项卡发生更改后收到QTabWidget::currentChanged信号,但是是否有QTabWidget::currentChanging信号或其他方式来实现我需要的行为?

5 个答案:

答案 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);
}

在鼠标点击阶段,可以检索当前选定选项卡的索引并准备切换(或取消切换,如我的示例中所做的那样)。