在QWindow中停靠现有的QWidget

时间:2015-07-03 22:00:07

标签: c# c++ qt c++11

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

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

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

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

4)为 frmMain.cs 上的3个按钮实现代码,如下所示(对于此实现,我们将实现&#34; Welcome&#34;按钮,将对象名称作为< strong> 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

**程序的使用**

当您点击&#34;欢迎&#34;按钮例如,结果应该是这样的:

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

...当您点击其他按钮时,请说出&#34;许可协议&#34;按钮,您可能会看到除当前选择之外的其他内容。

主要问题 我们如何通过应用&#34; QDockWidget&#34;来为QT CREATOR带来Windows Forms的简单性?

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

ui->dockWidget->setWidget(myWidget);

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

ui.Controls.Add(myWidget);

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

P.S。我很抱歉链接这些图片,我不会因为它们出现而声名鹊起......

3 个答案:

答案 0 :(得分:1)

  

我想要的是有一个程序与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提供了dock小部件的概念,也称为工具调色板或实用程序窗口。停靠窗口是放置在QMainWindow中央窗口小部件周围的停靠窗口小部件区域中的辅助窗口。

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

如何使用QtDesigner 执行此操作:

  1. 首先,您需要在右侧区域准备一个合适的用户界面(包含3个按钮和一个 QStackedWidget ,以便在单击其中一个添加的按钮后查看每个用户控件。)
  2. 为堆栈中的用户控件添加3个页面(如果您确实需要,则为&#34;空&#34;页面加一个)。如果您想在单独的UI文件/仅在代码中设计控件(而不是MainFrame中的所有控件),您可以将普通QWidgetpromote添加到适当的特定窗口小部件类型
  3. 在每个用户控件上插入内容...
  4. 在frmMain.cpp / .h上实现3个按钮的代码如下(对于这个实现,我们将实现&#34; Welcome&#34;按钮,将对象名称作为welcomeBtn,并且rest将具有相同的代码,但代之以不同的用户控件名称:

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

  5. 选择&#34;空&#34;页面位于设计器中的当前页面,因此程序在运行时最初会像这样结束:(您的屏幕截图)

  6. 当您点击&#34;欢迎&#34;按钮例如,结果应该是这样的:(你的第二个截图)

答案 1 :(得分:0)

首先,我们不能强迫其他框架如何对另一个框架起作用。每个框架都有其流程和设计。

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

  

void QDockWidget :: setWidget(QWidget * widget)

  将停靠窗口小部件的窗口小部件设置为窗口小部件   如果在添加窗口小部件时可以看到停靠窗口小部件,则必须显式地显示()它   请注意,在调用此函数之前,必须添加窗口小部件的布局;如果没有,小部件将不可见。

请在此分享myWidget的代码,以便我们尽力帮您找出问题所在。

在我这边,我可以通过在QVboxLayout添加ui->dockwidget并使用emtpy字符串添加QLabel来实现它,当您想要显示myWidget时,只需致电{ {1}}

答案 2 :(得分:0)

在我看来,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);