我需要旋转UI的某些元素(不是全部)。我已经尝试了很多东西,但没有一个能提供我需要的解决方案。
我试图使用QGraphicsProxyWidget和Graphics View,如果我想旋转整个UI,但是没有办法只旋转某些元素,那么这个效果很好。
我尝试将窗口小部件推广到覆盖paintEvent的自定义类。我无法通过这种方式工作。以下是我目前的代码
#include <QPushButton>
#include <QPainter>
#include <QPaintEvent>
class QRotateButton : public QPushButton
{
Q_OBJECT
public:
QRotateButton (QWidget *parent = 0) {}
protected:
void paintEvent(QPaintEvent *event) override {
if (isDrawing)
return QRotateButton::paintEvent(event);
isDrawing = true;
QPixmap buttonPixmap = grab();
QPainter painter(this);
painter.rotate(90);
painter.drawPixmap(0, 0, height(), width(), buttonPixmap);
isDrawing = false;
}
private:
bool isDrawing = false;
};
返回以下错误
QWidget::repaint: Recursive repaint detected
Segmentation fault
提前致谢
更新
根据以下评论,我更改了代码以致电QPushButton::paintEvent(Event)
而非QRotateButton::paintEvent(Event)
应用程序现在打开,之前没有。但遗憾的是没有按钮显示。每当现在调用paintEvent时,控制台中都会显示以下错误消息:
QWidget::repaint: Recursive repaint detected
QWidget::paintEngine: Should no longer be called
QPainter::begin: Paint device returned engine == 0, type: 1
QPainter::rotate: Painter not active
答案 0 :(得分:0)
在进一步解决这个问题之后,我设法弄明白了。
#include <QPushButton>
#include <QPainter>
#include <QPaintEvent>
class QRotateButton : public QPushButton
{
Q_OBJECT
public:
QRotateButton (QWidget *) {
//Set variables to defaults
_isDrawing = false;
_recursiveCounter = 0;
_recursiveMax = 1;
_rotationSetting = 0;
_rotationAngle = 0;
_rotationX = 0;
_rotationY = 0;
_rotationWidth = 0;
_rotationHeight = 0;
}
/* Set rotation setting */
void SetRotation(int setting) {
//Set rotation setting
_rotationSetting = setting;
//Call paintEvent
this->update();
}
protected:
void paintEvent(QPaintEvent *event) override {
//If its drawing then it just wants to do the normal paintEvent
if (_isDrawing)
{
QPushButton::paintEvent(event);
return;
}
//Setup the variables depending on setting
setupRotationVariables();
//Setup painter and rotate to angle
QPainter painter(this);
painter.rotate(_rotationAngle);
//Without this here, this function is called over and over,
//this stops that whilst maintaing the rotated image we want
if (_recursiveCounter > 0 && _requiresRotation)
{
_recursiveCounter--;
painter.drawPixmap(_rotationX, _rotationY, _drawing.width(), _drawing.height(), _drawing);
return;
}
//When rotating 90/270 degrees, we resize the image so that we don't stretch the image
//This is not required when flipping the image
if (_requiresRotation)
resize(_rotationWidth, _rotationHeight);
//Get the button image, this will call this function so we set _isDrawing to true whilst it's going on so meaning that it's does the base method and returns
_isDrawing = true;
_drawing = grab();
_isDrawing = false;
//Now we have the image, if rotation is being done resize the widget back to it's previous measurements
if (_requiresRotation)
resize(_rotationHeight, _rotationWidth);
//Draw the image to the picture
painter.drawPixmap(_rotationX, _rotationY, _drawing.width(), _drawing.height(), _drawing);
//Depending on if this has rotated or not, setup the catch the tailend of the rotation event
if (_requiresRotation)
_recursiveCounter = _recursiveMax;
else
_recursiveCounter = 0;
}
private:
/* Stops Recursive resizing when resizing is required */
int _recursiveCounter;
int _recursiveMax;
/* If the widget is currently drawing, stops certain recursive calls */
bool _isDrawing;
/* If the widget needs to rotated instead of flipped */
bool _requiresRotation;
/* Contains image of previous render of button, for use in recursive calls */
QPixmap _drawing;
/* Rotation Setting (0-3) defines rotation type. This is used since rotations should only be multiples of 90 */
int _rotationSetting;
/* Variables after rotation */
int _rotationAngle;
int _rotationX;
int _rotationY;
int _rotationWidth;
int _rotationHeight;
/* Fetch variables based on Rotation Setting */
void setupRotationVariables () {
//Figure out what rotation is required
switch (_rotationSetting)
{
case 0: //Up side up
_rotationAngle = 0;
_rotationWidth = width();
_rotationHeight = height();
_rotationX = 0;
_rotationY = 0;
_requiresRotation = false;
break;
case 1: //Right side up
_rotationAngle = 90;
_rotationWidth = height();
_rotationHeight = width();
_rotationX = 0;
_rotationY = -width();
_requiresRotation = true;
break;
case 2: //Down side up
_rotationAngle = 180;
_rotationWidth = width();
_rotationHeight = height();
_rotationX = -width();
_rotationY = -height();
_requiresRotation = false;
break;
case 3: //Left side up
_rotationAngle = 270;
_rotationWidth = height();
_rotationHeight = width();
_rotationX = -height();
_rotationY = 0;
_requiresRotation = true;
break;
default:
printf("INVALID ROTATION\n");
break;
}
}
};
每次调用paintEvent时,这仍然会抛出QWidget::repaint: Recursive repaint detected
,但是我们期望这个并且它在代码中处理。虽然我希望它不显示,但我无法找到任何阻止它的方法。