16,815
社区成员




刚学Qt+VS2022,Qt创建的MDI窗口项目,如何在主窗口设置当前子窗口的自定义public类型变量的值?
思路:在子窗口设置一个Checkbox,点击设置当前子窗口中自定义的一个变量值,为何在子窗口中无反应:
// 主窗口:setDrawLine_triggered() 用来设置子窗口中的m_bDraw_Line
void MyMainWindow::setDrawLine_triggered()
{
qDebug()<<"1: 设置前子--窗口中的:m_bDraw_Line="<<((childWidget*)ui->mdiArea->activeSubWindow())->m_bDraw_Line ;
((childWidget*)ui->mdiArea->activeSubWindow())->m_bDraw_Line = drawLineCheck.isChecked();
// 输出显示也设置成功了,但就是在子窗体中,鼠标移动画线还是默认的是true
qDebug()<<"2: 设置后--子窗口中的:m_bDraw_Line="<<((childWidget*)ui->mdiArea->activeSubWindow())->m_bDraw_Line ;
}
// 子窗口:鼠标移动画线
void childWidget::paintEvent(QPaintEvent *event)
{
qDebug()<<"m_Draw_Line:"<<m_Draw_Line;
// 问题:不管主窗体中CheckBox是否选中,一样画线。m_Draw_Line在构造函数设置为true。
if(m_bDraw_Line) DrawLine(m_Move_pos);
}
// 鼠标移动事件
void childWidget::mouseMoveEvent(QMouseEvent *event)
{
m_Move_pos = event->pos();
this->update();
}
// 另外,在主窗体用一个接口函数来设置m_Draw_Line。结果还是无反应。
void childWidget::setDrawLine(bool bdrawline)
{
m_bDraw_Line = bdrawline;
)
在使用Qt和VS2022创建MDI(多文档界面)窗口项目时,遇到在主窗口设置当前子窗口的自定义public类型变量的值却无反应的问题是比较常见的。从你提供的代码来看,有几个关键点需要注意。
首先,在主窗口中获取当前活动子窗口并设置其变量值的代码逻辑看起来基本正确,但可能存在类型转换不安全的问题。虽然你使用了(childWidget*)
进行强制类型转换,但更推荐使用qobject_cast
来进行安全的类型转换,例如:childWidget *activeChild = qobject_cast<childWidget*>(ui->mdiArea->activeSubWindow()->widget());
。如果转换失败,activeChild
将为nullptr
,这样可以避免一些潜在的错误。
paintEvent
中,确保m_Draw_Line
的值确实被正确读取和使用。
对于解决这个问题,一种更好的方式是通过信号和槽机制来实现主窗口和子窗口之间的通信。在Qt中,信号和槽是一种非常强大且灵活的机制。主窗口可以发出一个信号,例如setDrawLineSignal(bool value)
,子窗口可以定义一个对应的槽函数setDrawLineSlot(bool value)
,然后在子窗口的构造函数中使用connect
函数将主窗口的信号和子窗口的槽连接起来。这样可以确保在主窗口设置变量值时,子窗口能够正确接收到并处理这个变化。
推荐书籍 | 图书特点 |
---|---|
《C++ GUI Programming with Qt 4》(第二版) | 作者:Jasmin Blanchette、Mark Summerfield,出版社:Prentice Hall,适合初学者入门Qt编程,内容全面涵盖Qt基础概念、核心类库与GUI编程,示例丰富 |
《Mastering Qt 5》 | 作者:Guillaume Lazar、Robin Penea,出版社:Packt Publishing,针对Qt 5新特性全面讲解,深入MDI构建与性能优化等,适合深入学习Qt 5的读者 |
《Qt for Python Developers》 | 作者:Antonio Diaz - Cano,出版社:Packt Publishing,从Python开发者角度出发介绍Qt for Python开发,示例简洁,适合Python开发者入门Qt开发 |
搞定:
((childWidget*)ui->mdiArea->activeSubWindow()->widget())->m_bDraw_Line = drawLineCheck.isChecked();
思路:在子窗口设置一个Checkbox.......。
应为:思路:在主窗口设置一个Checkbox