关于子类化QGraphicsTextItem只有很小一部分区域能够获取事件的问题
来源:互联网 发布:超级玛丽 跳跃算法 编辑:程序博客网 时间:2024/05/23 14:57
在QT图形视图框架中,想要Item响应获得焦点事件,首先需要设置本Item可以获得焦点
一般Item可以使用
setFlag(QGraphicsItem::ItemIsFocusable);
来使Item可以获取焦点事件,但是针对QGraphicsTextItem,它有一个另外的设置方法,首先来看这个方法的函数原型
void setTextInteractionFlags(Qt::TextInteractionFlags flags)
帮助文档中对这个方法是这样解释的:
Sets the flags flags to specify how the text item should react to user input.
The default for a QGraphicsTextItem is Qt::NoTextInteraction. This function also affects the ItemIsFocusable QGraphicsItem flag by setting it if flags is different from Qt::NoTextInteraction and clearing it otherwise.
By default, the text is read-only. To transform the item into an editor, set the Qt::TextEditable flag.
这样就比较清晰了,参数flags代表了QGraphicsTextItem的一些属性,
再来看看Qt::TextInteractionFlags
This enum specifies how a text displaying widget reacts to user input.Constant Value DescriptionQt::NoTextInteraction 0 No interaction with the text is possible.Qt::TextSelectableByMouse 1 Text can be selected with the mouse and copied to the clipboard using a context menu or standard keyboard shortcuts.Qt::TextSelectableByKeyboard 2 Text can be selected with the cursor keys on the keyboard. A text cursor is shown.Qt::LinksAccessibleByMouse 4 Links can be highlighted and activated with the mouse.Qt::LinksAccessibleByKeyboard 8 Links can be focused using tab and activated with enter.Qt::TextEditable 16 The text is fully editable.Qt::TextEditorInteraction TextSelectableByMouse | TextSelectableByKeyboard | TextEditable The default for a text editor.Qt::TextBrowserInteraction TextSelectableByMouse | LinksAccessibleByMouse | LinksAccessibleByKeyboard The default for QTextBrowser.
它是一个枚举,每个枚举代表不同的QGraphicsTextItem属性,比如Qt::NoTextInteraction,设置这个属性的话QGraphicsTextItem就只是个能显示字符串的Item,没有输入,选中功能;而Qt::TextEditable表示启用QGraphicsTextItem的所有功能;QGraphicsTextItem默认属性为Qt::TextBrowserInteraction,这个属性是一个聚合属性,其中一个是TextSelectableByMouse,表明可以被鼠标选中,既然可以被选中,就表明可以获取焦点,我们可以使用
setTextInteractionFlags(Qt::TextBrowserInteraction);
来使得QGraphicsTextItem可以获取焦点。
当然
setFlag(QGraphicsItem::ItemIsFocusable);
对QGraphicsTextItem同样是有效的。
好了现在开始说正题:
问题:
子类化QGraphicsTextItem并setTextInteractionFlags(Qt::TextBrowserInteraction);,在paint事件中使用painter自行绘制想要显示的字符串
painter->drawText(boundingRect(),Qt::AlignCenter,m_text);
即使重写了boundingRect()虚函数,并返回了正确的区域,但是QGraphicsTextItem却只有很小一部分区域能够获取到事件
分析与解答:
在正确setFlag的情况下,依然无法获取到焦点事件,那么多半是boundingRect()的问题,我们有必要在paint事件中将boundingRect画出来,不过问题中说了,已经在重写的boundingRect虚函数返回了正确的QRectF区域,如下图所示,我们将boundingRect绘制出来
可以看到此时boundingRect完完全全的把QString包含起来,按照一般Item,点击boundingRect区域,应该会有鼠标事件,焦点事件发生,但事实却不尽然。
经过尝试,发现似乎即使重写QGraphicsTextItem的boundingRect函数,TextItem却视而不见,依然使用自身的一套系统来计算其有效区域,所以子类化QGraphicsTextItem并自行使用Painter绘制字体的时候,不仅要对painter setFont,还要对QGraphicsTextItem本身设置font与plainText,这样QGraphcisTextItem才能正确计算出自身的事件有效区域;
下面贴上代码:
frametext.h
#ifndef FRAMETEXT_H#define FRAMETEXT_H#include <QGraphicsTextItem>#include <QFontMetricsF>#include <QPen>class FrameText : public QGraphicsTextItem{public: FrameText(); ~FrameText(); QRectF boundingRect(); void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); void setText(QString); void setFontSize(int);private: QString m_text; QPen m_pen; QFont m_font; int m_fontSize; bool m_focus; QFontMetricsF *m_fontMetricsF; qreal m_fontWidth; qreal m_fontHeight; void updateFontInfo(); void focusInEvent(QFocusEvent *); void focusOutEvent(QFocusEvent *);};#endif // FRAMETEXT_H
frametext.cpp
#include "frametext.h"#include <QPainter>#include <QDebug>#include <QStyleOptionGraphicsItem>FrameText::FrameText(){ setTextInteractionFlags(Qt::TextEditorInteraction); m_fontMetricsF=Q_NULLPTR; m_text=""; m_font.setFamily("msyhl"); m_font.setPixelSize(20); m_focus=false;}FrameText::~FrameText(){ delete m_fontMetricsF;}QRectF FrameText::boundingRect(){// qDebug()<<"boundingRect"; return QRectF(0,0,m_fontWidth,m_fontHeight);}void FrameText::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){// qDebug()<<"paint"; painter->save(); if(m_focus==true) m_pen.setColor(Qt::blue); else m_pen.setColor(Qt::black); painter->setPen(m_pen); painter->setFont(m_font); painter->setRenderHint(QPainter::Antialiasing,true); painter->drawText(boundingRect(),Qt::AlignCenter,m_text); painter->drawRect(boundingRect()); painter->restore();}void FrameText::setText(QString text){ m_text=text; updateFontInfo();}void FrameText::setFontSize(int size){ m_fontSize=size; m_font.setPixelSize(m_fontSize); updateFontInfo();}void FrameText::updateFontInfo() //计算m_fontWidth,m_fontHeight给自定义的boundingRect使用,同时为QGraphicsTextItem设置font和plainText{ if(Q_NULLPTR!=m_fontMetricsF) delete m_fontMetricsF; m_fontMetricsF=new QFontMetricsF(m_font); m_fontWidth=m_fontMetricsF->width(m_text); m_fontHeight=m_fontMetricsF->height(); this->setFont(m_font); this->setPlainText(m_text);}void FrameText::focusInEvent(QFocusEvent *focusEvent) //获得焦点事件{ //qDebug()<<"focus in"; Q_UNUSED(focusEvent); m_focus=true; this->update();}void FrameText::focusOutEvent(QFocusEvent *focusEvent) //失去焦点事件{ Q_UNUSED(focusEvent); //qDebug()<<"focus out"; m_focus=false; this->update();}
为什么QGraphcisTextItem不使用重写的boungingRect虚函数,本人也是初学QT,如有高人知道还望指点一二,感激不尽!
- 关于子类化QGraphicsTextItem只有很小一部分区域能够获取事件的问题
- ios 获取图片的一部分区域
- 记录两个很小很小的问题
- 利用select_region_point算子可以通过区域内的一个点或者区域的一部分,获取完整区域
- 关于ListView只能显示一部分的问题
- 关于Arcgis地图中full extent很小的问题
- 获取字符串的一部分
- 获取QString的一部分
- 关于Java的一些很小很小的知识
- 关于java中父类引用子类实例化的问题
- 关于重启tomcat时请求执行一部分的问题
- 关于xib下tableview空出一部分的问题
- 【Android 问题集锦】关于android ImageView前景图片显示很小的问题
- 人能够改变的只有自己
- 关于js的事件获取遇到的问题
- 关于SDL多指触屏事件获取各手指状态的问题。
- 关于ViewGroup组件获取单击事件的问题
- 关于sql的一部分知识
- 638. Shopping Offers
- qwt
- azkaban基础操作
- IE与DOM事件流的区别
- 活用内核链表解决约瑟夫斯问题
- 关于子类化QGraphicsTextItem只有很小一部分区域能够获取事件的问题
- TDD、BDD与ATDD CI
- 选择子序列 51Nod
- php(一)
- JAVA基础——Java中的集合。
- 【Array、List】Java数组或集合中如何删除元素
- Android 学习资料汇总
- 继承中方法的重写和抽象类
- JAVA中23种设计模式之单例模式