将QDialog设置为外部窗口

5
在一个独立的GUI应用程序中,我没有窗口管理器或复合管理器,我想向用户显示一个QDialog以询问值。
对话框非常大,因此我想使其半透明,这样用户可以透过它看到在对话框显示时应用程序中发生的情况。
问题在于,要使X本地窗口半透明,需要有一个复合管理器。Qt内部小部件可以被绘制成半透明,因为它们不对应原生X窗口(外星人)并且完全只知道Qt。
是否有一种方法可以使QDialog的背景半透明而无需运行复合管理器?也许将其变成应用程序主窗口的普通子小部件/外星人?有更好的替代方案吗?

我相信您已经看到了这个链接 http://doc.qt.nokia.com/latest/qwidget.html#windowOpacity-prop 。"在 X11 下,您需要运行一个合成管理器,并且您正在使用的窗口管理器需要支持 X11 特定的 _NET_WM_WINDOW_OPACITY 原子。" - Chenna V
1
这是一个适合斯卡利和穆尔德的案件! - fredoverflow
撇开技术问题不谈,这似乎是一个不寻常的UI决策。我本人对应用程序自行决定采用这种半透明度持怀疑态度(与在窗口管理器中按每个应用程序的用户偏好完成相比)。如果您描述了您要做什么并在http://ux.stackexchange.com/上共享了图表/屏幕截图,也许您可以获得一些有用的替代界面建议。 - HostileFork says dont trust SE
@Hostile 很抱歉,我不能这样做。但感谢您提供的UX@SE链接! - Johannes Schaub - litb
您是否因为个人喜好或平台要求而未安装窗口管理器或合成管理器? - mattr-
1个回答

2
我不知道如何将QDialog转换为普通子小部件。查看Qt for X11代码,我无法找到一种方法来设置未传递给QWidget(父级)构造函数的Qt :: WindowFlags,以便它成为一个简单的小部件而不是自己的窗口(但我可能是错的,在此上没有花费太多时间)。
一个简单的替代方案是使用一个普通的QWidget作为容器,而不是QDialog。这里有一个示例“PopupWidget”,它绘制了半透明红色背景。
#include <QtGui>

class PopupWidget: public QWidget
{
 Q_OBJECT

 public:
  PopupWidget(QWidget *parent): QWidget(parent)
  {
   QVBoxLayout *vl = new QVBoxLayout;
   QPushButton *pb = new QPushButton("on top!", this);
   vl->addWidget(pb);
   connect(pb, SIGNAL(clicked()), this, SLOT(hide()));
  }

 public slots:
  void popup() {
   setGeometry(0, 0, parentWidget()->width(), parentWidget()->height());
   raise();
   show();
  }

 protected:
  void paintEvent(QPaintEvent *)
  {
   QPainter p(this);
   QBrush b(QColor(255,0,0,128));
   p.fillRect(0, 0, width(), height(), b);
  }
};

要显示它,调用它的 popup() 槽,它将把它提升到小部件堆栈的顶部,使其与其父级一样大,并显示它。这将掩盖其后面的所有小部件(您无法使用鼠标与它们交互)。当单击该按钮时,它会隐藏自己。
注意事项:
  • 这不会阻止用户使用 Tab 键访问下面的小部件。例如,可以通过在“常规”小部件容器上切换 enabled 属性来解决此问题。(但不要禁用 PopupWidget 的父级:这将禁用弹出式小部件本身。)
  • 这不允许使用像 QDialog::exec 这样的阻塞调用。
  • 该弹出窗口中的小部件将不透明,您需要为所需的所有小部件类型创建自定义透明背景版本。
但这可能比在您的环境中集成合成管理器更方便。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接