12

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

4

5 回答 5

9

就我而言,我像这样连接 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

    }
}
于 2015-08-28T08:18:21.107 回答
4

这就是我解决它的方法

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);
    }
}
于 2013-12-15T22:20:51.233 回答
1

在您的标题中,声明:

QWidget *saveTab

创建一个例程,为信号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
于 2015-09-03T21:00:16.240 回答
0

如果更改被禁止,则使用常规QTabWidget并在发出后返回上一个选项卡currentChanged对于用户来说看起来不正确,因为新选项卡在重新选择前一个选项卡之前可见,这是由于QTabWidget通知选项卡“已更改”,而不是“即将改变”。

一种选择是创建自己的QTabWidget. 感谢QTabBar,这很明显。

您还需要创建QTabWidgetlike 函数以“like” a 使用它QTabWidget,但您需要的函数并不多。

这是一个QTabWidget类似类的示例,aboutToChangeTab其中发出一个信号,通知选项卡即将更改,可以设置allowedfalse禁止选项卡更改。

#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) 并执行以下操作:

void MyWidget::allowTabChange( QWidget* curTab, QWidget* nextTab, bool* allowed )
{
    if ( !canChange( curTab, nextTab ) )
        *allowed = false;
}
于 2020-05-15T10:54:15.580 回答
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);
}

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

于 2021-08-06T15:55:13.640 回答