0

How do I recognize a double click on a tab in order to change its label? Preferrably I could edit the label in place but alternatively I could also get a string from another input box. Any suggestions? The tab gets added and the label specified currently like:

QString tab_label = QString("Shell (") + QString::number(session->id(), 16) + ")";
    addTab(session->widget(), tab_label);

and I'd want to be able to edit the label after creation.

Oh and I should mention here that I'm a Qt newbie, too!

EDIT1
full method:

int SessionStack::addSession(Session::SessionType type)
{
    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(), tab_label);

    emit sessionAdded(session->id());

    raiseSession(session->id());

    return session->id();
}
stdcerr
  • 13,725
  • 25
  • 71
  • 128

1 Answers1

2

There's a QTabBar::tabBarDoubleClicked signal, you just need to connect it to a slot to detect a double click. Also you'll need some widget to actually edit the tab's text. If you want it "out of place" (say, you open a dialog) then it should be enough to do something like:

connect(tabWidget->tabBar(), &QTabBar::tabBarDoubleClicked,
        this, MyWidget::editTabBarLabel);

void MyWidget::editTabBarLabel(int tabIndex)
{
    if (tabIndex < 0)
        return;
    // open dialog asking for the new label,
    // f.i. via QInputDialog::getText

    // set the new label bakc
}

If instead you want some in-place modification you'll need to more or less heavily modify QTabBar to do so.

The simplest option would be opening a QLineEdit on the right tab. To get the geometry of a tab via QTabBar:.tabrect, so that you can place the line edit in the same geometry. You'll very likely fall short on that path (see below) and you'll need to subclass QTabBar and use initStyleOption for the given tab, then set the lineedit's geometry to the right subrect (for instance, do not cover the "side widgets" of a tab).

Random pseudo braindumped code:

void MyTabBar::editTabBarLabel(int tabIndex)
{
    if (tabIndex < 0)
        return;

    if (!m_lineEdit) {
        m_lineEdit = new QLineEdit(this);
        // once done, commit the change, or abort it, anyhow
        // destroy/hide (?) the line edit
        connect(m_lineEdit, &QLineEdit::editingFinished,
                this, &MyTabBar::renameLabel);
    } else {
        // we're actually editing something else, what to do?
        // commit the other change and start editing here?
    }

    m_editedTabIndex = tabIndex; // remember which one we're editing
    m_lineEdit->setText(tabText(tabIndex));     

    // not "entirely" accurate, you need better subrect control here,
    // cf. QStyle and https://doc.qt.io/qt-5/style-reference.html#widget-walkthrough
    // that's why this should really be a QTabBar subclass, because
    // you'll need to invoke initStyleOption and then fetch the subrects from the style

    m_lineEdit->setGeometry(tabRect(tabIndex));
    m_lineEdit->show();
}

// also track resize of the tabbar, relayout, tab reorder, tab insertion and removal, etc.
// move the QLineEdit accordingly
peppe
  • 21,934
  • 4
  • 55
  • 70
  • Hi, I'm wondering what `tabWidget->` is (in `connect()`)..? I've added the code from the method that adds the session and the tab into my original post under **EDIT1** – stdcerr Sep 25 '16 at 22:22
  • It's the QTabWidget you have around. – peppe Sep 26 '16 at 10:58