Кастомизация QMessageBox C++ Qt

189
25 мая 2018, 07:50

Ранее я задавал вопрос:

Возможно ли в стандартном QMessageBox (чтобы свой диалог не писать), кнопки сделать по центру?

Я пробовал делать QHBoxLayout размещать в него 2 кнопки, а потом это лейаут добалять в QMessageBox. Не получилось.

Потом делал так:

QPushButton * abort = question.addButton("Abort", QMessageBox::NoRole);

И в стилях пытался марджинами поправить. Кнопка сдивнулась. Но проблема была в том, что марджин увеличивает размер виджета, и кнопка как бы больше становится, т.е. при клике правее кнопки она нажимается.

Я смог это реализовать так:

Распечатал все виджеты и их свойства у QMessageBox:

const auto widgets = msgbox->findChildren<QWidget*>();
for (const auto widget : widgets)
{
const QMetaObject * metaobject = widget->metaObject();
 int count = metaobject->propertyCount();
 for (int i=0; i<count; ++i)
 {
     QMetaProperty metaproperty = metaobject->property(i);
     const char * name = metaproperty.name();
     QVariant value = widget->property(name);
     qDebug() << "NAME : " << name << ", VALUE : " << value;
 }
}

У QMessageBox есть виджет qt_msgbox_buttonbox, к которому если обращаться по имени в файле .qss через #qt_msgbox_buttonbox и установив ему свойство qproperty-centerButtons: true. То кнопки выровняются по центру.

Теперь мне нужно сдвинуть картинку у QMessageBox. И здесь снова я встал в тупик.

В стилях я пробовал установить виджету qt_msgboxex_icon_label margin обращаясь к нему по имени #qt_msgboxex_icon_label в файле .qss. И вот в чем загвоздка. В Linux такой код работает, и картинка спокойно позиционируется, а вот в Windows нет.

Пробовал такой вот код использовать:

QGridLayout * grid = qobject_cast<QGridLayout*>(msgbox->layout());
    if (grid)
    {
        QLabel * label = qobject_cast<QLabel*>((grid->itemAtPosition(0, 0))->widget());
        if (label)
        {
            label->setContentsMargins(0, 0, 0, 0);
        }
    }

Но такой код двигает картинку, но не ее Label. Не могу в общем спозиционировать в нужное место картинку в QMessageBox

Answer 1

Не забывайте, что Qt - продукт с открытым исходным кодом, и всегда можно покапаться внутри исходников. Так, использую метаобъектную систему Qt, можно легко установить кнопки в диалоге по центру

QMessageBox *dlg = ...;
if(QDialogButtonBox * box = dlg->findChild<QDialogButtonBox*>(QString("qt_msgbox_buttonbox")))
  box->setCenterButtons(true);

А если еще немного извернуться, то и иконку можно подвинуть

QMessageBox *dlg = ...;
if(QLabel * lbl = dlg->findChild<QLabel*>("qt_msgboxex_icon_label")) {
  if(QGridLayout * lay = qobject_cast<QGridLayout*>(dlg->layout()) ) {
    // Перый элемент - иконка
    delete lay->takeAt(0);
    lay->addWidget(lbl, 0, 0, 1, 1, Qt::AlignCenter);
  }
}

Но использовать такое решение можно только на свой страх и риск: нет гарантий, что разработчики не поменяют что-то в будущих релизах.

READ ALSO
Заменить все нечетные элементы

Заменить все нечетные элементы

Помогите с написание метода: найти максимальное и минимальное значение и найденным максимальным значением заменить все нечетные значения...

189
Рефракторинг кода

Рефракторинг кода

Попытка переписать код немного не пошла, помогите переписать этот код под классы и методы

207
Перевод MAC адреса из string в u_char[]

Перевод MAC адреса из string в u_char[]

Подскажите как правильно перевести строку string с MAC адресом имеющую формат:

167
Как добавить маршалинг строки в функцию библиотеки, которая добавлена через reference?

Как добавить маршалинг строки в функцию библиотеки, которая добавлена через reference?

У меня подключена библиотека (неуправляемая) через reference

180