QT 窗体问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QT 窗体问题相关的知识,希望对你有一定的参考价值。

我要在中央窗体中打开一个新的窗体(通过一个按钮),那么怎么使新的窗体包含在主窗体之中,新窗体的边界范围不允许超出中央窗体。

子窗体用QDialog就可以了,然后dialog的parent设为中央窗体追问

class text : public QDialog

Q_OBJECT
public:
explicit text(QWidget *parent = 0);
~text();
text::text(QWidget *parent) :
QDialog(parent),
ui(new Ui::text)
void MainWindow::on_text_clicked()

text s(ui->centralWidget);
我只打出了主要实现功能的几行代码,效果是text对话框在子窗体内,但是text 对话框能够自由移动,并且可以移出中央窗体外面,那么该如何修改呢

追答

我估计你的意图式MDI吧,也就式多文档界面,也就式在一个窗口中可以有许多子窗口,但是均不能移出,你看一下Qt 助手里面的MainWindow里面的MDI例子便知道

追问

...........额,我看看,试试,但是那个背景怎么也继承下来了。。。。我背景不要变呢。。。。。

追答

看MDI了么,只有MDI才能符合子窗口移不出去啊

参考技术A 指定为中央窗体的子窗体
或者自己截获move事件.追问

呵呵,我是个菜鸟,不会弄中央窗体的子窗体,你能给出示例代码吗,可以给你加分的

在 Qt 中确定父窗体的类型

【中文标题】在 Qt 中确定父窗体的类型【英文标题】:Determining type of parent form in Qt 【发布时间】:2017-12-10 23:21:14 【问题描述】:

我有一个带有表 X 的数据库:我们称之为clients。我还有一个与编辑表 X 内容相关的表单。当需要从表 X 中“挑选”一条记录时,它可以自行打开(浏览/编辑)以及从其他表单中打开。

我如何告诉父母一个特定的QModelIndex 已直接从on_tableView_doubleClicked(const QModelIndex &index) 信号处理程序中挑选出来?

目前,我只有一个“爸爸”表单,所以我知道将哪种类型的指针放入子表单(因此它可以保存指向父表单的指针)并且只是转换了它的类型的指针。

if (parent) daddy = qobject_cast<InvoiceEd*>(parent);

现在我想从另一个表单添加一个调用,我意识到我必须从QWidget*指针中投射不同的指针,我不知道如何确定QWidget* parent指针下的“变相”是什么。我该怎么做?

【问题讨论】:

【参考方案1】:

我建议使用接口和dynamic_cast 来传递有关所选项目的信息:

InvoiceEdInterface.hpp:

class InvoiceEdInterface 
public:
    virtual void SetSelectedItem (SelectedItemClass i_selected_item) = 0;
;

InvoiceEd.hpp:

class InvoiceEd: public InvoiceEdInterface 
public:
    void SetSelectedItem (SelectedItemClass i_selected_item) override 
        // Process setting selected item.
    
;

DataForm.hpp

class DataForm 
...
    void on_tableView_doubleClicked(const QModelIndex &index) 
        auto invoice_ed dynamic_cast< InvoiceEdInterface* >(parent ());

        if (invoice_ed) 
            invoice_ed->SetSelectedItem (...);
        
    
...
;

解决方案背后的想法非常简单:如果父窗口小部件实现了指定的接口,则调用SetSelectedItem()。否则,什么都不会发生。

但是请注意,建议的解决方案可能不是Qt-ish。使用 Qt,您可以添加一个通知所选项目的信号。当在父控件中创建DataForm 对象以选择某个项目时,父控件应建立信号槽连接。这种解决方案比上面提出的解决方案更灵活,因为它允许程序中的任何对象获取有关所选项目的信息。

两种建议的解决方案都可以动态工作,不受基于模板的解决方案的限制。

【讨论】:

如果指针可以转换为QObject*,那么qobject_cast 应该是一个更轻松的调用。至少对于较旧的 C++,许多人避免 dynamic_cast 只是因为它需要将 RTTI 添加到可执行文件中。不过,现在更频繁地使用动态转换。我猜处理器变得更快和更多内存。 @AlexanderVX,你是对的,qobject_cast 也可以用来达到同样的效果。显示基于dynamic_cast 的方法有两个原因:1) 我忘记了qobject_cast,2) 它不仅可以用于基于 QObject 的类,因此更通用。基于dynamic_cast 的方法的另一个优点是它不需要您编写任何额外的代码——一切都在RTTI 的帮助下自动运行。而且我认为只有在有某些原因(例如分析结果或最小可执行文件大小的要求)时才应避免使用 RTTI。 你好,我在子窗体中公开了tableView,并在创建子窗体后将它的信号简单地连接到父窗体中的插槽。它有效!所以我会接受你的回答,因为你建议重新考虑信号槽连接【参考方案2】:

在一些现有的方法实现中有一段代码可以解析小部件类型:

// dataform.cpp
void DataForm::myEdit()

   ///
   if (parent()) daddy = qobject_cast<InvoiceEd*>(parent());

作者想让它更灵活,例如根据调用者具体转换为某些小部件类型。这是可以做到的。让我们将所需的类型传递给它:

class DataForm

   public:
   // was void myEdit()
   template <typename T = InvoiceEd> // defaults to InvoiceEd
     void myEdit()
     
         ///
         T* daddy = qobject_cast<T*>(parent());
         // now we operate with the proper pointer so that
         // exact instance does virtual function calls etc.
     
///
;

pDataForm->myEdit(); // default case
pDataForm->myEdit<MutatedInvoiceEd>(); // specified case

附:以上没有批评有问题的设计。在 OOP 中,我们通常不希望知道调用方法的上下文,或者对象不希望彼此识别。在这种情况下,您应该为不同的用途创建两种不同的方法,或者可能提供一个附加参数(可能具有默认值 void myEdit(bool insideOfContainerEdit = true) 以便代码了解一些主要用例。有很多方法可以处理它,但我们看不到你的全部代码。

当然,C++ 中模板的存在使我们能够在一定程度上解决问题。我自己在模板中找到帮助,有时可以避免编写更多代码或从类型等派生,但过度使用这种方法会导致很多头痛。理想情况下,我们应该要么依赖多态继承,要么完全通过带有参数类型的模板来处理这种情况。

【讨论】:

对我来说,如果它是一个独立的调用,我似乎可以在没有参数的情况下知道,因为我在表单的构造函数中有这个 QWidget* 指针,当它出现时它将是 == 0是一个。所以我只是在我当前的类中添加了两个带有两个方法的模板(将构造函数放入其中以存储指针和信号处理程序以从存储的指针中调用不同的方法)? 从设计的角度来看:类接口通常越少越好。但当然,事情应该是有效的。

以上是关于QT 窗体问题的主要内容,如果未能解决你的问题,请参考以下文章

Qt将窗体变为顶层窗体

qt如何设置打开的窗体一直在最上层

QT 如何最小化窗体

qt中如何添加窗体背景图片?如何改变窗体背景颜色?

qt 窗体透明,控件不透明

qt中怎么让窗体中的控件随着窗体自动缩放