我正在使用 aQTabWidget
并且我需要一种方法来在当前选项卡实际发生之前处理它的更改,并且如果满足某些条件可能会取消它。在QTabWidget::currentChanged
当前选项卡更改后收到信号,但是是否有QTabWidget::currentChanging
信号或其他方式来实现我需要的行为?
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
}
}
这就是我解决它的方法
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);
}
}
在您的标题中,声明:
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
如果更改被禁止,则使用常规QTabWidget
并在发出后返回上一个选项卡currentChanged
对于用户来说看起来不正确,因为新选项卡在重新选择前一个选项卡之前可见,这是由于QTabWidget
通知选项卡“已更改”,而不是“即将改变”。
一种选择是创建自己的QTabWidget
. 感谢QTabBar
,这很明显。
您还需要创建QTabWidget
like 函数以“like” a 使用它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
) 并执行以下操作:
void MyWidget::allowTabChange( QWidget* curTab, QWidget* nextTab, bool* allowed )
{
if ( !canChange( curTab, nextTab ) )
*allowed = false;
}
有一个简单的事件过滤器解决方案,不需要继承 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);
}
在鼠标单击阶段,可以检索当前选定选项卡的索引并准备切换(或取消切换,如我的示例中所做的那样)。