PDA

View Full Version : QMessageBox Details button label



frog
6th April 2011, 20:15
I'm seeking for a solution to change the label of the "Show Details..."/"Hide Details..." button of a message box.
I did it for a role based button, but this peculiar button is not in the role list and I m wondering how to get access to the button pointer to handle this.

stampede
7th April 2011, 08:47
I think this text is hardcoded in Qt sources (at least in 4.5.2):


// qmessagebox.cpp, lines 121 - 123
QString label(DetailButtonLabel label)
{ return label == ShowLabel ? QMessageBox::tr("Show Details...")
: QMessageBox::tr("Hide Details..."); }

I have a working solution, it's not very nice but maybe you can use it.
Buttons are added in showEvent, so I've reimplemented it in order to get pointer to "hide/show details" button, it's added to the box with ActionRole. Next I've connected it to slot that will change it's text each time it's clicked. Here is the class:


// MyMsgBox.h

class MyMsgBox : public QMessageBox{
Q_OBJECT
public:
MyMsgBox( QWidget * parent = NULL ) : QMessageBox(parent){
details = NULL;
}
MyMsgBox( Icon icon, const QString & title, const QString & text, StandardButtons buttons = NoButton, QWidget * parent = 0, Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint )
:QMessageBox(icon,title,text,buttons,parent,f)
{
details = NULL;
}
void setDetailedText( const QString& text );
void setDetailsButtonText( const QString& t1, const QString& t2 );
protected:
virtual void showEvent( QShowEvent * event );
protected slots:
void detailsClicked();
protected:
QString _t1, _t2;
QAbstractButton * details;
};



// MyMsgBox.cpp

void MyMsgBox::setDetailedText( const QString& text ){
QMessageBox::setDetailedText(text);
details = NULL;
}

void MyMsgBox::setDetailsButtonText( const QString& t1, const QString& t2 ){
_t1 = t1;
_t2 = t2;
}

void MyMsgBox::detailsClicked(){
QAbstractButton * btn = qobject_cast<QAbstractButton*>(sender());
if( btn ){
if( btn->text() == tr("Show Details...") and _t1!=QString() ){
btn->setText(_t1);
} else if( _t2!=QString() ){
btn->setText(_t2);
}
}
}

void MyMsgBox::showEvent( QShowEvent * event ){
QMessageBox::showEvent(event);
if( details == NULL ){
foreach( QAbstractButton * btn, this->buttons() ){
if( buttonRole(btn) == QMessageBox::ActionRole and btn->text() == QMessageBox::tr("Show Details...") ){
details = btn;
connect(details, SIGNAL(clicked()), this, SLOT(detailsClicked()));
if( _t1 != QString() ){
details->setText(_t1);
}
break;
}
}
}
}

test app:


int main(int argc, char *argv[])
{
QApplication a(argc, argv);

MyMsgBox msg(QMessageBox::Information, "title", "text");
msg.setDetailsButtonText("text1","text2");
msg.setDetailedText("details");
msg.show();


return a.exec();
}

As I've said, it's not very nice solution and I'm not even sure if it will work in new versions of Qt, but maybe you can use it somehow :)

Cupidvogel
20th June 2015, 23:50
Doesn't work in Qt 5.3, 32 bit, Mac. The this->buttons() method returns an empty QList.