我怎么能在另一个小部件中使用 QColorDialog 而不是单独的对话框?

Posted

技术标签:

【中文标题】我怎么能在另一个小部件中使用 QColorDialog 而不是单独的对话框?【英文标题】:How could I use the QColorDialog inside another widget not as a separate dialog? 【发布时间】:2010-10-27 16:21:42 【问题描述】:

我不想将QColorDialog 用作对话窗口,而是用作可以插入到布局中的小部件。 (更具体地说,作为上下文菜单中的自定义子菜单)

我查看了 QColorDialog 源代码,我可能会复制 QColorDialog 的部分内部实现来实现这一点,但是有没有更简洁的方法来做到这一点?我正在使用 Qt 4.5.1...

【问题讨论】:

【参考方案1】:

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】:

您可以通过设置正确的窗口标志以非常简单的方式做到这一点。

QColorDialog8 colorDialog = new ....
colorDialog->setWindowFlags(Qt::SubWindow);

【讨论】:

【参考方案3】:

您可能想查看一些 Qt 解决方案,它们至少可以完成您想要的部分功能。例如,请参阅Color Picker 解决方案,他们注意到现在也可作为 LGPL 许可的库使用。

作为一种替代方法(可能支持较少的方法),我记得 Qt-Labs 中关于将 Qt 小部件(包括 QDialogs)嵌入到 QGraphicsScene 中的一些工作。您可能会这样做,然后更改图形场景上的视图,以便只有您感兴趣的颜色选择器对话框的部分对用户可见。然而,这听起来很骇人听闻。

【讨论】:

找不到此解决方案。有更新的产品链接吗?【参考方案4】:

尝试继承 QColorDialog

【讨论】:

【参考方案5】:

使用QGraphicsView 并添加QDialog。如果要显示对话框,请将QGraphicsView 添加到小部件。

【讨论】:

【参考方案6】:

基于@Wiz 的回答,我使用一些 C++11 功能(lambdas 和 auto;适用于 VS2010 和带有 Qt 5.1.1 的 gcc 4.6)从工具栏按钮上制作了一个弹出菜单:

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

【讨论】:

请注意,您修改后的代码不再是 Qt4,因为此问题已被标记。 对。除了 connect() 调用需要稍微不同的语法来使用 lambdas 作为插槽之外,您是否注意到任何其他不兼容性?【参考方案7】:

基于“金属”的先前回答,我建议您在 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);

这将自动处理任何对话框。

【讨论】:

【参考方案8】:

如果有办法干净地做到这一点,我不知道。在我看来,您有两种选择:

对其进行子类化并复制实际构建小部件的代码,进行编辑以删除创建对话窗口的部分并将其替换为其他容器。 如果您不打算使用该特定对话框,qt 解决方案中的颜色三角形小部件可能会起作用,因为它不是对话框窗口。您可以在 http://doc.trolltech.com/solutions/4/qtcolortriangle/qtcolortriangle.html 找到它(删除链接中的空格)

【讨论】:

有可能。请参阅下面@Wiz 的解决方案。

以上是关于我怎么能在另一个小部件中使用 QColorDialog 而不是单独的对话框?的主要内容,如果未能解决你的问题,请参考以下文章

如何在另一个小部件中管理小部件状态

fltk 小部件顺序,按钮隐藏在另一个小部件下

Android:如何使用 ConstraintLayout 在另一个小部件上显示一个小部件?

使用 Flutter Provider 时,SignalR 客户端颤振库在另一个小部件中显示空值

QWidget 在另一个小部件上

Listview.builder 将一个小部件定位在另一个小部件上