【问题标题】:How to dynamically swap QWidgets如何动态交换 QWidgets
【发布时间】:2017-11-15 23:43:07
【问题描述】:

我有一个 QMainWindow,左侧包含一个 QTreeWidget,右侧包含另一个 QMainWindow,其中 windowFlags 设置为 Qt::Widget。

这是因为 QMainWindow 是向 QWidget 提供停靠功能的唯一方法。 (如果需要,我希望停靠的组件完全从“真实”窗口中弹出。

我的问题是我希望用户能够保持弹出的停靠小部件,即使他们的项目没有在左侧被选中。

例如,这里是全局布局:

假设我选择了第 1 项。在右侧我将有一些可停靠的小部件,我可以根据需要重新排序。如果我弹出一个来关注它,如果我选择第 2 项,我不希望它消失。

更进一步,如果我愿意,我可能想一次显示所有项目的可停靠小部件。

我最初的想法是让每个项目都有其专用的 QMainWindow 存储在其数据中,我只需切换正确的 QMainWindow 以反映当前活动的那个。

也许我想要的是一个坏主意,也许它甚至不可行。

有一些 Qt 知识的人可以告诉我,如果我在做/想要做错什么吗?

编辑:

如果有一种方法可以手动触发“内部 QMainWindow”弹出,那对我来说非常好。例如,右上角的“弹出”按钮将完全弹出并使其成为一个全新的窗口(但仍链接到另一个窗口)

编辑2:

我想指出我还没有尝试过关于这个问题的任何事情。我基本上想知道它是否符合 Qt 的做事方式。

This 的问题让我很高兴能够只为程序的一部分提供对接功能,但我仍然不确定我想要什么。我真的能做到吗?

Edit7,MVCE:

希望我没有忘记任何事情,因为这是通过修改我的文件来完成的。

mainwindow2.cpp

#include "mainwindow2.hh"
#include "ui_mainwindow2.h"
#include <QTreeWidgetItem>

MainWindow2::MainWindow2(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow2)
{
    ui->setupUi(this);
    ui->mainPanel->setWindowFlags(Qt::Widget);
    QTreeWidgetItem* item = new QTreeWidgetItem;
    item->setData(0, 0, QVariant::fromValue(QString("Item 1")));
    ui->accountsTreeWidget->addTopLevelItem(item);
    QTreeWidgetItem* item2 = new QTreeWidgetItem;
    item2->setData(0, 0, QVariant::fromValue(QString("Item 2")));
    ui->accountsTreeWidget->addTopLevelItem(item2);
}

MainWindow2::~MainWindow2()
{
    delete ui;
}

mainwindow2.hh

#ifndef MAINWINDOW2_HH
#define MAINWINDOW2_HH

#include <QMainWindow>

namespace Ui {
class MainWindow2;
}

class MainWindow2 : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow2(QWidget *parent = 0);
    ~MainWindow2();

private:
    Ui::MainWindow2 *ui;
};

#endif // MAINWINDOW2_HH

mainwindow2.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow2</class>
 <widget class="QMainWindow" name="MainWindow2">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1200</width>
    <height>700</height>
   </rect>
  </property>
  <property name="minimumSize">
   <size>
    <width>1200</width>
    <height>700</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>Main Window</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <property name="minimumSize">
    <size>
     <width>1200</width>
     <height>658</height>
    </size>
   </property>
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="1" rowspan="2" colspan="2">
     <widget class="QMainWindow" name="mainPanel"/>
    </item>
    <item row="0" column="0">
     <widget class="QTreeWidget" name="accountsTreeWidget">
      <property name="minimumSize">
       <size>
        <width>200</width>
        <height>0</height>
       </size>
      </property>
      <property name="maximumSize">
       <size>
        <width>300</width>
        <height>16777215</height>
       </size>
      </property>
      <property name="frameShape">
       <enum>QFrame::NoFrame</enum>
      </property>
      <property name="selectionBehavior">
       <enum>QAbstractItemView::SelectItems</enum>
      </property>
      <property name="uniformRowHeights">
       <bool>true</bool>
      </property>
      <attribute name="headerVisible">
       <bool>false</bool>
      </attribute>
      <column>
       <property name="text">
        <string notr="true">1</string>
       </property>
      </column>
     </widget>
    </item>
   </layout>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <connections/>
</ui>

main.cpp

#include "mainwindow2.hh"
#include <QApplication>
#include <QStyleFactory>

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    app.setStyle(QStyleFactory::create("Fusion"));

    MainWindow2 w;
    w.show();

    return app.exec();
}

project.pro

#-------------------------------------------------
#
# Project created by QtCreator 2017-11-12T23:07:49
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = project
TEMPLATE = app

DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

INCLUDEPATH += $$PWD

SOURCES += \
        main.cpp \
        mainwindow2.cpp

HEADERS += \
        mainwindow2.hh

FORMS += \
        mainwindow2.ui

【问题讨论】:

  • 因为你的声誉,你必须知道你必须提供一个MVCE。 ;P
  • @eyllanesc 我知道这是一个很好的加分,但我现在正在工作,它更像是“有可能吗?”一种问题! :p
  • 还有一张用我的 MSPaint 技能烘焙的漂亮图片
  • 我的要求是能够拥有一个能够测试的代码,我不想花时间从头开始创建小部件,这就是为什么我要求您提供 MVCE 或您通过 github 或类似方式提供您的代码。我根据您的句子下订单: 我有 一个 QMainWindow ,左侧包含 QTreeWidget ,右侧包含另一个 QMainWindow ,其中 windowFlags 设置为 Qt : :小部件。
  • 是的,我明白了。这只是一个 .ui 文件。稍后我会更新主帖。

标签: c++ qt qt5 qt5.9


【解决方案1】:

在右侧,您可以添加一个带有QBoxLayout 的父小部件,将所有项目附加到它,然后根据需要隐藏、显示和排序它们。

将它们设为自定义类,并使用公共 int 变量让您稍后识别它们。将它们的指针存储在QList 中,然后循环列表并根据您的条件隐藏或显示项目(使用 int 变量)。

示例:

项目来自类别 A -> int 值 0
项目来自类别 B -> int value 1
等等……

【讨论】:

  • 如何处理弹出窗口“应该”隐藏的情况?
  • 你不能让一个小部件同时停靠并显示为一个独立的窗口,你应该创建一个代表独立窗口的可停靠项目,或者只是复制项目并显示两次(停靠和独立)。
  • 你应该检查this的答案。
  • 不,我不想复制东西,但是如果我的列表的每个项目中有 3 或 4 个可停靠选项卡,并且只想弹出一个,我仍然可以替换“视图”吗?离开了?也许有一种方法可以更容易地从我的真实窗口中弹出整个“sub-QMainWindow”?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2010-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多