Qt 父窗口A移动,A中有QTabWidget对象 B ,B中有 一个QLabel C,窗口D 无父窗口且只在C中有指针窗口D的指针,不可以在窗口A,窗口B中操作C和D,移动A时,如何使得窗口D一直在窗口C上方? 此问题中如果仅重写resizeEvent事件,当A移动时,D并不会跟着移动。有什么方式能解决。不可以通过重写A的moveEvent事件,不可以通过重写QLabel C的paintEvent事件来实现。不可以在A中操作D
时间: 2023-10-02 10:13:05 浏览: 60
你可以重写A的resizeEvent事件,获取C的位置和大小,然后计算出D相对于C的位置,并将D移动到对应位置。代码示例如下:
```cpp
void A::resizeEvent(QResizeEvent *event) {
QWidget::resizeEvent(event);
QRect cRect = B->mapToGlobal(C->geometry()).translated(-B->mapToGlobal(QPoint(0, 0)));
QPoint dPos = cRect.topLeft() - QPoint(0, D->height());
D->move(B->mapFromGlobal(dPos));
}
```
在该代码中,我们使用了`B->mapToGlobal(C->geometry())`获取C在全局坐标系中的位置和大小,然后使用`translated`将其转换为相对于窗口B的位置和大小。之后,我们计算出D相对于C的位置,即C的左上角位置向上偏移D的高度,最后使用`B->mapFromGlobal`将其转换为窗口B的坐标系中的位置,并将D移动到该位置。这样,无论A如何移动和调整大小,D都会一直保持在C的上方。
相关问题
Qt 事件父窗口A移动,A中有QTabWidget对象 B ,B中有 一个QLabel C,窗口D 无父窗口且只在C中,移动A,如何使得窗口D一直在窗口C上方
可以通过重载 `QWidget::moveEvent()` 方法来实现。在父窗口 A 移动时,通过 `QLabel::mapToGlobal()` 方法获取子窗口 D 在屏幕上的坐标,然后再通过 `QLabel::mapFromGlobal()` 方法将其转换为相对于子窗口 C 的坐标,最后通过 `QWidget::move()` 方法将子窗口 D 移动到正确的位置上。
下面是一个示例代码:
```cpp
class MyLabel : public QLabel {
public:
MyLabel(QWidget* parent) : QLabel(parent) {
m_childWindow = new QWidget(this);
m_childWindow->setFixedSize(100, 100);
m_childWindow->setStyleSheet("background-color: red;");
}
protected:
void moveEvent(QMoveEvent* event) override {
if (m_childWindow) {
QPoint globalPos = m_childWindow->mapToGlobal(QPoint(0, 0));
QPoint localPos = mapFromGlobal(globalPos);
m_childWindow->move(localPos.x(), localPos.y() - m_childWindow->height());
}
QLabel::moveEvent(event);
}
private:
QWidget* m_childWindow;
};
```
在上面的代码中,我们创建了一个自定义的 QLabel 子类 MyLabel,它包含了一个名为 m_childWindow 的子窗口。在 MyLabel 的 `moveEvent()` 方法中,我们首先调用父类 QLabel 的 `moveEvent()` 方法,然后通过 `m_childWindow->mapToGlobal(QPoint(0, 0))` 获取子窗口 D 在屏幕上的坐标,并将其转换为相对于 MyLabel 的坐标。最后,我们通过 `m_childWindow->move()` 方法将子窗口 D 移动到正确的位置上。
Qt 事件父窗口A移动,A中有QTabWidget对象 B ,B中有 一个QLabel C,窗口D 无父窗口且只在C中有指针窗口D的指针,不可以在窗口A,窗口B中有D的指针,移动A时,如何使得窗口D一直在窗口C上方?
可以通过重写QLabel的resizeEvent()函数,在该函数中判断窗口D是否已经创建,如果已经创建,则设置窗口D的位置为C的位置加上偏移量,偏移量可以通过计算C的大小和D的大小来确定。同时,在窗口A的moveEvent()函数中也要判断窗口D是否已经创建,如果已经创建,则调用D的move()函数来更新其位置。
下面是示例代码:
```cpp
class MyLabel : public QLabel {
public:
MyLabel(QWidget *parent = nullptr) : QLabel(parent) {}
protected:
void resizeEvent(QResizeEvent *event) override {
QLabel::resizeEvent(event);
if (m_dWindow) {
QPoint pos = mapToParent(m_dOffset);
m_dWindow->move(pos);
}
}
public:
void setDWindow(QWidget *dWindow) {
m_dWindow = dWindow;
updateDOffset();
}
void updateDOffset() {
if (m_dWindow) {
QSize cSize = size();
QSize dSize = m_dWindow->size();
m_dOffset = QPoint((cSize.width() - dSize.width()) / 2, -dSize.height());
}
}
private:
QWidget *m_dWindow = nullptr;
QPoint m_dOffset;
};
class MyWidget : public QWidget {
public:
MyWidget(QWidget *parent = nullptr) : QWidget(parent) {
m_tabWidget = new QTabWidget(this);
m_label = new MyLabel(m_tabWidget);
m_label->setPixmap(QPixmap(":/image/image.png"));
m_tabWidget->addTab(m_label, "Label");
setWindowTitle("My Widget");
}
protected:
void moveEvent(QMoveEvent *event) override {
QWidget::moveEvent(event);
if (m_label) {
m_label->updateDOffset();
}
if (m_dWindow) {
QPoint pos = mapToGlobal(m_label->pos() + m_label->rect().center() + m_label->dOffset());
m_dWindow->move(pos);
}
}
public:
void setDWindow(QWidget *dWindow) {
m_dWindow = dWindow;
if (m_label) {
m_label->setDWindow(m_dWindow);
}
}
private:
QTabWidget *m_tabWidget = nullptr;
MyLabel *m_label = nullptr;
QWidget *m_dWindow = nullptr;
};
```
在主窗口中创建MyWidget和另一个窗口D,然后调用MyWidget的setDWindow()函数来设置窗口D。注意,窗口D需要设置为无父窗口,否则它会跟随父窗口移动。同时,调用MyLabel的updateDOffset()函数来计算偏移量。
阅读全文