我一直收到此错误,我也不知道为什么。它只是说我的类FrameLess的类型不完整。我不认为我会丢失任何文件。我还想指定除此小部件外还有一个主窗口,并且我试图为我的类FrameLess实现UI窗体。任何帮助都会很棒。谢谢!
frameless.h
#ifndef FRAMELESS_H
#define FRAMELESS_H
#pragma once
#include <QtWidgets/QWidget>
#include <QtWidgets/QRubberBand>
#include <QtCore/QObject>
#include <QtCore/QEvent>
#include <QtCore/QRect>
#include <QtCore/QPoint>
#include <QtCore/Qt>
#include <QtGui/QHoverEvent>
#include <QtGui/QMouseEvent>
#include <QMainWindow>
namespace Ui {
class FrameLess;
}
class FrameLess : public QObject {
Q_OBJECT
public:
enum Edge {
None = 0x0,
Left = 0x1,
Top = 0x2,
Right = 0x4,
Bottom = 0x8,
TopLeft = 0x10,
TopRight = 0x20,
BottomLeft = 0x40,
BottomRight = 0x80,
};
Q_ENUM(Edge);
Q_DECLARE_FLAGS(Edges, Edge);
FrameLess(QWidget *target);
void setBorderWidth(int w) {
_borderWidth = w;
}
int borderWidth() const {
return _borderWidth;
}
protected:
bool eventFilter(QObject *o, QEvent *e) override;
void mouseHover(QHoverEvent*);
void mouseLeave(QEvent*);
void mousePress(QMouseEvent*);
void mouseRealese(QMouseEvent*);
void mouseMove(QMouseEvent*);
void updateCursorShape(const QPoint &);
void calculateCursorPosition(const QPoint &, const QRect &, Edges &);
private:
QWidget *_target = nullptr;
QRubberBand *_rubberband = nullptr;
bool _cursorchanged;
bool _leftButtonPressed;
Edges _mousePress = Edge::None;
Edges _mouseMove = Edge::None;
int _borderWidth;
Ui::FrameLess *ui;
QPoint _dragPos;
bool _dragStart = false;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(FrameLess::Edges);
#endif
frameless.cpp:
#include "frameless.h"
#include "ui_frameless.h"
FrameLess::FrameLess(QWidget *target) :_target(target),_cursorchanged(false),_leftButtonPressed(false),_borderWidth(5),_dragPos(QPoint()), ui(new Ui::FrameLess)
{
// ui->setup(this);
_target->setMouseTracking(true);
_target->setWindowFlags(Qt::FramelessWindowHint);
_target->setAttribute(Qt::WA_Hover);
_target->installEventFilter(this);
_rubberband = new QRubberBand(QRubberBand::Rectangle);
}
bool FrameLess::eventFilter(QObject *o, QEvent*e) {
if (e->type() == QEvent::MouseMove ||
e->type() == QEvent::HoverMove ||
e->type() == QEvent::Leave ||
e->type() == QEvent::MouseButtonPress ||
e->type() == QEvent::MouseButtonRelease) {
switch (e->type()) {
case QEvent::MouseMove:
mouseMove(static_cast<QMouseEvent*>(e));
return true;
break;
case QEvent::HoverMove:
mouseHover(static_cast<QHoverEvent*>(e));
return true;
break;
case QEvent::Leave:
mouseLeave(e);
return true;
break;
case QEvent::MouseButtonPress:
mousePress(static_cast<QMouseEvent*>(e));
return true;
break;
case QEvent::MouseButtonRelease:
mouseRealese(static_cast<QMouseEvent*>(e));
return true;
break;
}
}
else {
return _target->eventFilter(o, e);
}
}
void FrameLess::mouseHover(QHoverEvent *e) {
updateCursorShape(_target->mapToGlobal(e->pos()));
}
void FrameLess::mouseLeave(QEvent *e) {
if (!_leftButtonPressed) {
_target->unsetCursor();
}
}
void FrameLess::mousePress(QMouseEvent *e) {
if (e->button() & Qt::LeftButton) {
_leftButtonPressed = true;
calculateCursorPosition(e->globalPos(), _target->frameGeometry(), _mousePress);
if (!_mousePress.testFlag(Edge::None)) {
_rubberband->setGeometry(_target->frameGeometry());
}
if (_target->rect().marginsRemoved(QMargins(borderWidth(), borderWidth(), borderWidth(), borderWidth())).contains(e->pos())) {
_dragStart = true;
_dragPos = e->pos();
}
}
}
void FrameLess::mouseRealese(QMouseEvent *e) {
if (e->button() & Qt::LeftButton) {
_leftButtonPressed = false;
_dragStart = false;
}
}
void FrameLess::mouseMove(QMouseEvent *e) {
if (_leftButtonPressed) {
if (_dragStart) {
_target->move(_target->frameGeometry().topLeft() + (e->pos() - _dragPos));
}
if (!_mousePress.testFlag(Edge::None)) {
int left = _rubberband->frameGeometry().left();
int top = _rubberband->frameGeometry().top();
int right = _rubberband->frameGeometry().right();
int bottom = _rubberband->frameGeometry().bottom();
switch (_mousePress) {
case Edge::Top:
top = e->globalPos().y();
break;
case Edge::Bottom:
bottom = e->globalPos().y();
break;
case Edge::Left:
left = e->globalPos().x();
break;
case Edge::Right:
right = e->globalPos().x();
break;
case Edge::TopLeft:
top = e->globalPos().y();
left = e->globalPos().x();
break;
case Edge::TopRight:
right = e->globalPos().x();
top = e->globalPos().y();
break;
case Edge::BottomLeft:
bottom = e->globalPos().y();
left = e->globalPos().x();
break;
case Edge::BottomRight:
bottom = e->globalPos().y();
right = e->globalPos().x();
break;
}
QRect newRect(QPoint(left, top), QPoint(right, bottom));
if (newRect.width() < _target->minimumWidth()) {
left = _target->frameGeometry().x();
}
else if (newRect.height() < _target->minimumHeight()) {
top = _target->frameGeometry().y();
}
_target->setGeometry(QRect(QPoint(left, top), QPoint(right, bottom)));
_rubberband->setGeometry(QRect(QPoint(left, top), QPoint(right, bottom)));
}
}
else {
updateCursorShape(e->globalPos());
}
}
void FrameLess::updateCursorShape(const QPoint &pos) {
if (_target->isFullScreen() || _target->isMaximized()) {
if (_cursorchanged) {
_target->unsetCursor();
}
return;
}
if (!_leftButtonPressed) {
calculateCursorPosition(pos, _target->frameGeometry(), _mouseMove);
_cursorchanged = true;
if (_mouseMove.testFlag(Edge::Top) || _mouseMove.testFlag(Edge::Bottom)) {
_target->setCursor(Qt::SizeVerCursor);
}
else if (_mouseMove.testFlag(Edge::Left) || _mouseMove.testFlag(Edge::Right)) {
_target->setCursor(Qt::SizeHorCursor);
}
else if (_mouseMove.testFlag(Edge::TopLeft) || _mouseMove.testFlag(Edge::BottomRight)) {
_target->setCursor(Qt::SizeFDiagCursor);
}
else if (_mouseMove.testFlag(Edge::TopRight) || _mouseMove.testFlag(Edge::BottomLeft)) {
_target->setCursor(Qt::SizeBDiagCursor);
}
else if (_cursorchanged) {
_target->unsetCursor();
_cursorchanged = false;
}
}
}
void FrameLess::calculateCursorPosition(const QPoint &pos, const QRect &framerect, Edges &_edge) {
bool onLeft = pos.x() >= framerect.x() - _borderWidth && pos.x() <= framerect.x() + _borderWidth &&
pos.y() <= framerect.y() + framerect.height() - _borderWidth && pos.y() >= framerect.y() + _borderWidth;
bool onRight = pos.x() >= framerect.x() + framerect.width() - _borderWidth && pos.x() <= framerect.x() + framerect.width() &&
pos.y() >= framerect.y() + _borderWidth && pos.y() <= framerect.y() + framerect.height() - _borderWidth;
bool onBottom = pos.x() >= framerect.x() + _borderWidth && pos.x() <= framerect.x() + framerect.width() - _borderWidth &&
pos.y() >= framerect.y() + framerect.height() - _borderWidth && pos.y() <= framerect.y() + framerect.height();
bool onTop = pos.x() >= framerect.x() + _borderWidth && pos.x() <= framerect.x() + framerect.width() - _borderWidth &&
pos.y() >= framerect.y() && pos.y() <= framerect.y() + _borderWidth;
bool onBottomLeft = pos.x() <= framerect.x() + _borderWidth && pos.x() >= framerect.x() &&
pos.y() <= framerect.y() + framerect.height() && pos.y() >= framerect.y() + framerect.height() - _borderWidth;
bool onBottomRight = pos.x() >= framerect.x() + framerect.width() - _borderWidth && pos.x() <= framerect.x() + framerect.width() &&
pos.y() >= framerect.y() + framerect.height() - _borderWidth && pos.y() <= framerect.y() + framerect.height();
bool onTopRight = pos.x() >= framerect.x() + framerect.width() - _borderWidth && pos.x() <= framerect.x() + framerect.width() &&
pos.y() >= framerect.y() && pos.y() <= framerect.y() + _borderWidth;
bool onTopLeft = pos.x() >= framerect.x() && pos.x() <= framerect.x() + _borderWidth &&
pos.y() >= framerect.y() && pos.y() <= framerect.y() + _borderWidth;
if (onLeft) {
_edge = Left;
}
else if (onRight) {
_edge = Right;
}
else if (onBottom) {
_edge = Bottom;
}
else if (onTop) {
_edge = Top;
}
else if (onBottomLeft) {
_edge = BottomLeft;
}
else if (onBottomRight) {
_edge = BottomRight;
}
else if (onTopRight) {
_edge = TopRight;
}
else if (onTopLeft) {
_edge = TopLeft;
}
else {
_edge = None;
}
}
答案 0 :(得分:0)
我通过重新创建一个简单的项目并复制您的代码,使其成为“ Qt Designer表单类”(我认为您也这样做),来进行尝试,并重新创建了与您相同的错误。
但是,看一下代码示例,这实际上并不是要成为 QDialog ,而是要成为 QObject ,即从主要Qt基类派生的类( QObject
)。因此,不应以这种方式使用它。
我查看了代码,并在构造函数中看到了以下几行:
FrameLess::FrameLess(QWidget *target) :_target(target),_cursorchanged(false),_leftButtonPressed(false),_borderWidth(5),_dragPos(QPoint()), ui(new Ui::FrameLess)
{
// ui->setup(this);
_target->setMouseTracking(true);
_target->setWindowFlags(Qt::FramelessWindowHint);
_target->setAttribute(Qt::WA_Hover);
_target->installEventFilter(this);
_rubberband = new QRubberBand(QRubberBand::Rectangle);
}
可以看出,此类接收了一个目标小部件并修改该小部件,使其无框架(例如,通过设置相应的窗口标志,属性等)。因此,在您要使用它的类中,正确的用例应该是这样的:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
new FrameLess(this);
}
构造函数调用(new Frameless(this)
)将以这种方式修改传递给它的对象。
因此,要使您的示例正常运行,请在Qt Creator中将其 recreate 作为普通的 QObject 派生类,或者只是进行快速测试,请从此删除构造函数的一部分:
FrameLess::FrameLess(QWidget *target) :_target(target),_cursorchanged(false),_leftButtonPressed(false),_borderWidth(5),_dragPos(QPoint()), ui(new Ui::FrameLess)
...最后的, ui(new Ui::FrameLess)
部分。即不要为ui
类成员分配任何内容。
在.h
文件中,删除此部分:
private:
QWidget *_target = nullptr;
QRubberBand *_rubberband = nullptr;
bool _cursorchanged;
bool _leftButtonPressed;
Edges _mousePress = Edge::None;
Edges _mouseMove = Edge::None;
int _borderWidth;
Ui::FrameLess *ui; // <- remove this
QPoint _dragPos;
bool _dragStart = false;
通过进行这些更改,我可以使您的示例正常工作,但是最好重新创建它/从项目中删除frameless.ui
对话框-无论如何都不会使用,因此最好将其删除。
希望这会有所帮助! :-)