Как я могу использовать QColorDialog внутри другого виджета, а не как отдельный диалог? - PullRequest
8 голосов
/ 20 мая 2009

Я хотел бы использовать QColorDialog не как диалоговое окно, а как виджет, который я мог бы вставить в макет. (Более конкретно, в качестве пользовательского подменю в контекстном меню)

Я посмотрел исходный код QColorDialog и, возможно, мог бы скопировать часть внутренней реализации QColorDialog, чтобы достичь этого, но есть ли более чистый способ сделать это? Я использую Qt 4.5.1 ...

Ответы [ 8 ]

17 голосов
/ 26 января 2013

QColorDialog - это диалог, который означает, что ЭТО - виджет. Все, что вам нужно сделать, это установить несколько оконных флагов и вставить их в свой макет, как вы хотите. Вот (проверенный) пример:

#include <QApplication>
#include <QMainWindow>
#include <QColorDialog>

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

    /* setup a quick and dirty window */
    QMainWindow app;
    app.setGeometry(250, 250, 600, 400);

    QColorDialog *colorDialog = new QColorDialog(&app);
    /* set it as our widiget, you can add it to a layout or something */
    app.setCentralWidget(colorDialog);
    /* define it as a Qt::Widget (SubWindow would also work) instead of a dialog */
    colorDialog->setWindowFlags(Qt::Widget);
    /* a few options that we must set for it to work nicely */
    colorDialog->setOptions(
                /* do not use native dialog */
                QColorDialog::DontUseNativeDialog
                /* you don't need to set it, but if you don't set this
                    the "OK" and "Cancel" buttons will show up, I don't
                    think you'd want that. */
                | QColorDialog::NoButtons
    );

    app.show();
    return a.exec();
}
2 голосов
/ 01 марта 2012

Вы можете сделать это очень просто, установив флажки в правом окне.

QColorDialog8 colorDialog = new ....
colorDialog->setWindowFlags(Qt::SubWindow);
2 голосов
/ 20 мая 2009

Возможно, вы захотите взглянуть на некоторые решения Qt, которые сделают хотя бы часть того, что вы хотите. Например, см. Решение Color Picker , которое, как они отмечают, теперь доступно и в виде библиотеки, лицензированной LGPL.

В качестве альтернативного (и, вероятно, менее поддерживаемого) подхода я вспоминаю некоторые работы в Qt-Labs по встраиванию виджетов Qt, включая QDialog s, в QGraphicsScene. Вы могли бы потенциально сделать это, а затем изменить представление вашей графической сцены так, чтобы только часть интересующего вас диалогового окна выбора цвета была видна пользователю. Это звучит очень хакерски, однако.

0 голосов
/ 20 июня 2014

Основываясь на предыдущем ответе от "metal", я предлагаю вам создать следующий метод в производном классе QAction:

void MyQAction::setPopupDialog(QDialog* dialog) {

  QWidgetAction* action = new QWidgetAction(NULL);
  action->setDefaultWidget(dialog);

  QMenu* menu = new QMenu();
  menu->addAction(action);
  // Fix issues related to the way the dialogbox hide/show. Restablish proper handling,
  // based on our requirement.
  connect(menu, SIGNAL(aboutToShow()), dialog, SLOT(show()));
  connect(dialog, SIGNAL(finished(int)), menu, SLOT(hide()));

  setMenu(menu);
}

это автоматизирует процесс для любого диалогового окна.

0 голосов
/ 22 октября 2013

Основываясь на ответе @ Wiz, я создал всплывающее меню на кнопке панели инструментов, используя некоторые функции C ++ 11 (lambdas и auto; работает с VS2010 и gcc 4.6 с Qt 5.1.1):

auto dialog = new QColorDialog();
dialog->setWindowFlags( Qt::Widget );
dialog->setOptions( QColorDialog::DontUseNativeDialog | QColorDialog::ShowAlphaChannel );

auto action = new QWidgetAction( 0 );
action->setDefaultWidget( dialog );

auto menu = new QMenu();
menu->addAction( action );

// The dialog-as-widget closes on Ok/cancel, but the menu that holds it 
// doesn't. We connect the two here. Because the dialog hides itself,
// we need to reshow it when the menu is coming up again.
connect( menu,   &QMenu::aboutToShow,     [=] { dialog->show(); } );
connect( dialog, &QColorDialog::rejected, [=] { menu->hide();   } );
connect( dialog, &QColorDialog::colorSelected,
    [=]( const QColor& color )
    {
        menu->hide();
        OnFillColorChanged( color ); // Call the "slot" in this class
    });

auto button = new QToolButton();
button->setIcon( QIcon( ":/images/whatev.png") );
button->setText( tr("Fill") );
button->setStatusTip( tr("Choose fill color") );
button->setMenu( menu );
button->setPopupMode( QToolButton::InstantPopup );
button->setToolButtonStyle( Qt::ToolButtonTextUnderIcon );

toolbar->addWidget( button ); // toolbar is defined elsewhere
0 голосов
/ 17 декабря 2009

Используйте QGraphicsView и добавьте к нему QDialog. И добавьте QGraphicsView к виджету, если хотите показать диалоговое окно.

0 голосов
/ 20 мая 2009

Если есть способ сделать это чисто, я не знаю об этом. На мой взгляд, у вас есть несколько вариантов:

  • Создайте его подкласс и скопируйте код, который фактически создает виджет, внося изменения, чтобы удалить часть, которая создает диалоговое окно, и заменить ее другим контейнером.
  • Если вы не настроены на использование этого конкретного диалога, виджет цветового треугольника из решений qt может работать, потому что это не диалоговое окно. Вы можете найти его по адресу http://doc.trolltech.com/solutions/4/qtcolortriangle/qtcolortriangle.html (удалить пробел из ссылки)
0 голосов
/ 20 мая 2009

Попробуйте создать подкласс QColorDialog

...