我想使用QColorDialog不是作为对话框窗口,而是作为可以插入到布局中的小部件。(更具体地说,作为上下文菜单中的自定义子菜单)
我查看了 QColorDialog 源代码,我可能可以复制 QColorDialog 内部实现的一部分来实现这一点,但是有没有更简洁的方法来做到这一点?我正在使用 Qt 4.5.1 ...
我想使用QColorDialog不是作为对话框窗口,而是作为可以插入到布局中的小部件。(更具体地说,作为上下文菜单中的自定义子菜单)
我查看了 QColorDialog 源代码,我可能可以复制 QColorDialog 内部实现的一部分来实现这一点,但是有没有更简洁的方法来做到这一点?我正在使用 Qt 4.5.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();
}
您可以通过设置正确的窗口标志以非常简单的方式将其清理干净。
QColorDialog8 colorDialog = new ....
colorDialog->setWindowFlags(Qt::SubWindow);
您可能想查看一些 Qt 解决方案,它们至少可以完成您想要的部分功能。例如,请参阅Color Picker解决方案,他们注意到它现在也可作为 LGPL 许可的库使用。
作为一种替代方法(并且可能支持较少),我记得 Qt-Labs 中关于将 Qt 小部件(包括QDialog
s)嵌入到QGraphicsScene
. 您可能会这样做,然后更改图形场景上的视图,以便只有您感兴趣的颜色选择器对话框的部分对用户可见。然而,这听起来很骇人听闻。
尝试继承 QColorDialog
使用QGraphicsView
并添加QDialog
到它。QGraphicsView
如果要显示对话框,请添加到小部件。
基于@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
基于“金属”的先前回答,我建议您在 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);
}
这将使任何对话框的过程自动化。
如果有办法干净地做到这一点,我不知道。在我看来,你有几个选择: