Capture DoubleClick on QTabBar



  • Hi,

    First off, I'm a Qt newbie:
    I'm trying to capture a double click on a QTabBar to execute a function that will let me change its label.
    Looks like my method editTabLabel never gets triggered though, I don't ever see the messageBox to pop up when I double click anywhere on the QTabBar.
    My code looks like:

    int SessionStack::addSession(Session::SessionType type)
    {
      int session_id = -1;
      
        Session* session = new Session(type, this);
        connect(session, SIGNAL(titleChanged(int,QString)), this, SIGNAL(titleChanged(int,QString)));
        connect(session, SIGNAL(terminalManuallyActivated(Terminal*)), this, SLOT(handleManualTerminalActivation(Terminal*)));
        connect(session, SIGNAL(activityDetected(Terminal*)), m_window, SLOT(handleTerminalActivity(Terminal*)));
        connect(session, SIGNAL(silenceDetected(Terminal*)), m_window, SLOT(handleTerminalSilence(Terminal*)));
        connect(session, SIGNAL(destroyed(int)), this, SLOT(cleanup(int)));
    
        m_sessions.insert(session->id(), session);
    
        QString tab_label = QString("Shell (") + QString::number(session->id(), 16) + ")";
        addTab(session->widget(), tr(qPrintable(tab_label)));
    
        emit sessionAdded(session->id());
    
        raiseSession(session->id());
        
        session_id = session->id();
     connect(this, SIGNAL(&QTabBar::tabBarDoubleClicked(session_id)),
        this, SLOT(SessionStack::editTabLabel(session_id)));
    
        return session->id();   
    }
    
    void SessionStack::editTabLabel(int tabIndex)
    {
      
          QMessageBox *msgBox = new QMessageBox();
          msgBox->setText("editTabBarLabel");
          msgBox->setWindowModality(Qt::NonModal);
          msgBox->setInformativeText("in editTabLabel()");
          msgBox->setStandardButtons(QMessageBox::Ok);
          msgBox->setDefaultButton(QMessageBox::Ok);
          int ret = msgBox->exec();
      
        if (tabIndex < 0)
            return;
        // open dialog asking for the new label,
        // f.i. via QInputDialog::getText
    
        // set the new label bakc
    }
    

  • Qt Champions 2016

    Hi
    Your connect look odd to me. like old and new syntax.

    connect(this, SIGNAL(&QTabBar::tabBarDoubleClicked(session_id)),
    this, SLOT(SessionStack::editTabLabel(session_id)));
    when you use & and :: do not use SIGNAL and SLOT macros.

    also the use of "this" seems not right.
    the syntax is
    connect( pointer to object 1, the signal, pointer to object 2, the slot in obj 2 )
    so you are saying

    connect(SessionStack, SIGNAL(&QTabBar::tabBarDoubleClicked(session_id)),
    SessionStack, SLOT(SessionStack::editTabLabel(session_id)));

    Is the signal not from TabBar? You say its from SessionStack

    also connect returns true or false and it's worth checking out.

    Maybe I read your code wrong but tabBarDoubleClicked seems like your signal? so i assume that your subclassed
    TabBar will emit it?



  • Hi mrjj,

    Thank you for your reply. I can follow through with what you say but have troubles to understand, how I get the handle from my tab added with addTab() to use in connect? I understand that this is the element that will emit the tabBarDoubleClicked signal. So how do I refer to it with connect()?

    Thanks,
    Ron


  • Qt Champions 2016

    http://doc.qt.io/qt-4.8/qtabbar.html#addTab
    it returns the index so you can use that to get tab object.

    But Its still not clear to me where signal tabBarDoubleClicked comes from?
    Did you subclass QTabBar and emit this signal on MousePress?

    is SessionStack a QTabBar ?



  • The class is declared as follows:

    class SessionStack : public QTabWidget
    

    How would I get the tab object using the index?


  • Qt Champions 2016

    @cerr
    hi
    Use this function to get the tab
    http://doc.qt.io/qt-4.8/qtabwidget.html#widget

    Can you show me how you define
    tabBarDoubleClicked ?



  • @mrjj said in Capture DoubleClick on QTabBar:

    @cerr
    hi
    Use this function to get the tab
    http://doc.qt.io/qt-4.8/qtabwidget.html#widget

    Can you show me how you define
    tabBarDoubleClicked ?

    I hadn't defined it at all but noew added it under

    signals:
        void tabBarDoubleClicked(int index);
    

    which still doesn't seem to be right, I now refer to it like:
    ```
    connect(QTabWidget::widget(tabIndex), SIGNAL(&QTabBar::tabBarDoubleClicked(sessionId)),
    this, SLOT(SessionStack::editTabLabel(sessionId)));

    and get this in the shell:
    

    No such signal Splitter::&QTabBar::tabBarDoubleClicked(sessionId)

    How do I make it link to the correct function/signal? :o


  • @mrjj said in Capture DoubleClick on QTabBar:

    @cerr
    hi
    Use this function to get the tab
    http://doc.qt.io/qt-4.8/qtabwidget.html#widget

    Can you show me how you define
    tabBarDoubleClicked ?

    I hadn't defined it at all but noew added it under

    signals:
        void tabBarDoubleClicked(int index);
    

    which still doesn't seem to be right, I now refer to it like:

    connect(QTabWidget::widget(tabIndex), SIGNAL(&QTabBar::tabBarDoubleClicked(sessionId)),
      this, SLOT(SessionStack::editTabLabel(sessionId)));
    

    and get this in the shell:

    No such signal Splitter::&QTabBar::tabBarDoubleClicked(sessionId)
    

    How do I get rid of Splitter:: and make it link to the correct function/signal? :o


  • Qt Champions 2016

    Hi
    First of all the signal:
    signals:
    void tabBarDoubleClicked(int index);

    In which class did you put it?
    You seems to say its the Tab. Is this correct? The signal is defined in Tab class ?

    Also, the syntax seems off. You are mixing syntaxes again.

    connect(QTabWidget::widget(tabIndex), SIGNAL(&QTabBar::tabBarDoubleClicked(sessionId)),
    this, SLOT(SessionStack::editTabLabel(sessionId)));

    try
    with
    QWidget *TheTab= ui->THEQTabWidget->widget(tabIndex);
    qDebug() << " con :" connect( TheTab , SIGNAL(tabBarDoubleClicked(sessionId) ), this, SLOT(editTabLabel(sessionId) );

    it should say "con : true "



  • @mrjj
    I now have:

    QWidget *tabWidget = QTabWidget::widget(tabIndex);
        connect(tabWidget, SIGNAL(tabBarDoubleClicked(sessionId)),this, SLOT(SessionStack::editTabLabel(sessionId)));
    

    where

    signals:	
    void tabBarDoubleClicked(int index);
    

    is declared in

    class SessionStack : public QTabWidget
    

    but I get this on the shell:

    QObject::connect: No such signal Splitter::tabBarDoubleClicked(sessionId)
    

    I don't exacltly understand where it gets the reference to Splitter:: from. There is a class that looks like:

    class Session;
    
    class Splitter: public QSplitter
    {
        Q_OBJECT
    
        public:
            explicit Splitter(Qt::Orientation orientation, Session* session, QWidget* parent);
            ~Splitter();
            Session* session();
    
            void recursiveCleanup();
        private:
            Session *m_session;
    };
    

    but QSplitter has no DoubleClicked signal.


  • Qt Champions 2016

    Hi
    Clean the build folder and run qmake again

    seems it remembers the bad syntax where you used
    &Splitter::tabBarDoubleClicked(sessionId)


  • Qt Champions 2016

    Also something else:

    you say:
    signals:
    void tabBarDoubleClicked(int index);
    is declared in class SessionStack : public QTabWidget

    but when you connect to say its in the tabWidget

    QWidget *tabWidget = QTabWidget::widget(tabIndex);
    connect(tabWidget, SIGNAL(tabBarDoubleClicked(sessionId)),this, SLOT(SessionStack::editTabLabel(sessionId)));

    here u say that tabWidget has the signal. Which seems NOT correct?

    and please stop using SessionStack:: with SLOT macro.
    Might still work, but NOT correct.

    • SLOT(editTabLabel(sessionId)));



  • @mrjj

    I deleted all files within build/, re-ran cmake and recompiled but still get:
    QObject::connect: No such signal Splitter::tabBarDoubleClicked(sessionId)

    I have now removed the declaration for tabBarDoubleClicked from class SessionStack - do I need it there? As it should come directly from QTabWidget, should it not?


  • Lifetime Qt Champion

    Hi,

    Because Splitter::tabBarDoubleClicked(sessionId) is wrong. You don't pass a variable to the connect statement, you pass the parameter type.


  • Qt Champions 2016

    @SGaist
    Good catch :)

    it should be
    connect(this, SIGNAL(tabBarDoubleClicked(int)),this, SLOT(editTabLabel(int)));

    • I have now removed the declaration for tabBarDoubleClicked from class SessionStack - do I need it there? As it should come directly from QTabWidget, should it not?

    I went and looked at doc for TabBar.
    http://doc.qt.io/qt-5/qtabbar.html#tabBarDoubleClicked
    It is indeed the bar that sends the db click.
    i thought it was a custom signal. sorry about that.
    So it is pretty simple
    (inside SessionStack )
    qDebug() << "con:" << connect(this, SIGNAL(tabBarDoubleClicked(int)),this, SLOT(editTabLabel(int)));

    that should do it. Check it says true.



  • @mrjj
    Oh yeah! Wow, cool!
    Thank you for helping the newbie!!! Much appreciated!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.