繁体   English   中英

在 QWindow 中停靠现有的 QWidget

[英]Docking an existing QWidget in QWindow

对于那些非常熟悉 C# 或 VB.NET 使用 .NET Framework(这是我认为最热门的框架)中的UserControl组件的人,您习惯于添加几个预览不同用户控件的按钮,如下所示:

1) 首先,您将准备一个适当的用户界面(包含 3 个按钮和右侧区域的单个面板,用于在单击添加的按钮之一后查看每个用户控件)。

2) 从解决方案资源管理器中添加 3 个用户控件...

3)在每个用户控件上插入内容...

4) 在frmMain.cs上实现 3 个按钮的代码如下(对于这个实现,我们将实现带有对象名称welcomeBtn的“欢迎”按钮,其余的将具有相同的代码但不同的用户控件名称) :

private void welcomeBtn_Click(object sender, EventArgs e)
{
    //Clear up everything from the panel if any item exist(s)...
    mainPanel.Controls.Clear();

    //Create a new instance of a user control for the button...
    UserControl1_Welcome welcome = new UserControl1_Welcome();

    //Show up the created instance of the user control
    mainPanel.Controls.Add(welcome);
}

5) 最后,程序在运行时最初会是这样的:

http://i.stack.imgur.com/OENwG.png

** 程序使用 **

例如,当您单击“欢迎”按钮时,结果应该是这样的:

http://i.stack.imgur.com/iCyo3.png

...当您单击不同的按钮时,比如说“许可协议”按钮,您会希望看到除当前选择之外的其他内容。

主要问题我们如何通过应用“QDockWidget”在 QT CREATOR 中带来 Windows 窗体的简单性?

我尝试插入 QDockWidget 组件没有问题,但是当我尝试执行等效的 .NET 代码以在 QDockWidget 中添加 QWidget 时:

ui->dockWidget->setWidget(myWidget);

我认为这相当于 C#.NET 中的这行代码(如果我错了,请纠正我):

ui.Controls.Add(myWidget);

使用此代码后,我的程序不会崩溃,也不会显示任何正在运行的东西...

PS我很抱歉链接图像,我没有10个让它们出现的声誉......

我想要的是有一个程序与 C# 示例(显示基于单击按钮的用户控件)执行相同的操作。

如果你想根据按钮点击显示特定的小部件,我建议使用QStackedWidget一个简单的例子是这样的:

// In the constructor of your CustomWidget

// Create your buttons
QPushButton* firstButton = new QPushButton("First Button", this);
QPushButton* secondButton = new QPushButton("Second Button", this);
QPushButton* thirdButton = new QPushButton("Third Button", this);

// Create your (custom) widgets
QLabel* firstPageWidget = new QLabel("First Label", this);
QLabel* secondPageWidget = new QLabel("Second Label", this);
QLabel* thirdPageWidget = new QLabel("Third Label", this);

// Add them to the stackWidget
/*QStackedWidget* */ m_stackedWidget = new QStackedWidget(this);
m_stackedWidget->addWidget(firstPageWidget);
m_stackedWidget->addWidget(secondPageWidget);
m_stackedWidget->addWidget(thirdPageWidget);

// Insert buttons and stackWidget to CustomWidget 

QVBoxLayout* layoutStack = new QVBoxLayout();
layoutStack->addWidget(m_stackedWidget);

QVBoxLayout* layoutButtons = new QVBoxLayout();
layoutButtons->addWidget(firstButton);
layoutButtons->addWidget(secondButton);
layoutButtons->addWidget(thirdButton);

QHBoxLayout* layout = new QHBoxLayout();
layout->addLayout(layoutButtons);
layout->addLayout(layoutStack);
setLayout(layout);

// Connect button clicks to slots
connect(firstButton, SIGNAL(clicked()), this, SLOT(onFirstButtonClicked()));
connect(secondButton, SIGNAL(clicked()), this, SLOT(onSecondButtonClicked()));
connect(thirdButton, SIGNAL(clicked()), this, SLOT(onThirdButtonClicked()));

然后更改插槽中当前可见的小部件

void CustomWidget::onFirstButtonClicked() {
    m_stackedWidget->setCurrentIndex(0);
}
void CustomWidget::onSecondButtonClicked() {
    m_stackedWidget->setCurrentIndex(1);
}
void CustomWidget::onThirdButtonClicked() {
    m_stackedWidget->setCurrentIndex(2);
}

请注意,如果您希望单击按钮只是为了更改一些文本(而不是更改可见小部件),您可能最好使用QTextEdit而不是QStackedWidget ,并在插槽中调用setText("....")

如果你有很多按钮,你最好使用QSignalMapper来限制插槽的数量。

另外,我不明白你为什么提到QDockWidget,因为它们有一个非常具体的用法:

QDockWidget 类提供了一个小部件,它可以停靠在 QMainWindow 内或作为桌面上的顶级窗口浮动。

QDockWidget 提供了停靠窗口小部件的概念,也称为工具面板或实用程序窗口。 停靠窗口是位于 QMainWindow 中中央小部件周围的停靠小部件区域中的辅助窗口。

如果你只是想要一个单独的窗口,你可能正在寻找一个QDialog

如何使用 QtDesigner 做到这一点

  1. 首先,您需要准备一个合适的用户界面(包含 3 个按钮和一个位于右侧区域的QStackedWidget ,用于在单击添加的按钮之一后查看每个用户控件)。
  2. 为堆栈中的用户控件添加 3 个页面(如果您确实需要,则为“空”页面添加一个页面)。 如果你想在不同的UI文件来设计控制/只有代码(而不是在你的主机的所有控件),你会增加普通QWidget S和 促进他们到合适的特定组件类型
  3. 在每个用户控件上插入内容...
  4. frmMain.cpp/.h 上 3 个按钮的实现代码如下(对于这个实现,我们将实现带有对象名称welcomeBtn 的“欢迎”按钮,其余的将具有相同的代码但不同的用户控件名称代替):

    void FrmMain::on_welcomeBtn_clicked() { ui->stack->setCurrentWidget(ui->welcomeWidget); }

  5. 在设计器中选择“空”页面作为当前页面,因此程序在运行时最初会像这样结束:(您的屏幕截图)

  6. 例如,当您单击“欢迎”按钮时,结果应该是这样的:(您的第二个屏幕截图)

首先,我们不能将其他框架的工作方式强加给另一个框架。 每个框架都有其流程和设计。

我的理解是您想在主窗口中显示另一个小部件。 如果你想使用QDockWidget ,它在文档上说是这样的:

void QDockWidget::setWidget(QWidget * widget)

将停靠小部件的小部件设置为小部件。
如果添加小部件时停靠小部件可见,则必须显式地 show() 它。
注意在调用这个函数之前必须添加widget的布局; 如果没有,小部件将不可见。

请在此处分享您的myWidget代码,以便我们可以尝试帮助您找出问题所在。

在我的身边,我可以通过添加实现它QVboxLayout你的ui->dockwidget并添加QLabel与emtpy字符串,当你想显示myWidget只是调用ui->dockwidget->vboxlayout->replaceWidget(label, myWidget);

在我看来,Miki 的答案是此用例的唯一正确方法(使用QStackedWidget )。

为了完整起见,我将演示如何在 Qt 中完成与 .NET 中使用的相同的Clear 和 Add方法:

// Assume controlPanel is a QWidget where you want to place the items
// Assume that controlPanel has set a layout (e.g. QHBoxLayout)

// Clear: Remove all Items from layout
QLayoutItem *child;
while ((child = controlPanel->layout()->takeAt(0)) != NULL) {
    delete child;
}

// Now widgets are still there, but not layouted. Delete them explicitly
foreach (QWidget * w, controlPanel->findChildren<QWidget*>()) {
    w->deleteLater();
}

// Now controlPanel is cleared

// Add new control
controlPanel->layout()->addWidget(new MyNewControlWidget);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM