C++ GUI Qt 4 编程-第八章 基于项的图形视图

11 篇文章 0 订阅

//修改1——20170626

经过几周的奋斗,每天几个小时的研究,总算大致把书上的历程自己给实现了一遍,很多相似功能知识做了个例子,并没有做的全面,原因是一方面由于,时间的限制,18号就去上班了,但本职工作并不是和软件相关,软件只是个兴趣,以后没有这么多时间去研究,另一方面很多功能相似,操作都类似,就没有必要再去实施一遍了,这样比较省时间吧。下面是自己的研究的大致过程,简单的东西就没再写了:

1、搞懂QGraphicsItem中:boundingRect()和paint()成员函数的使用方式


boundingRect()其实就是决定了整个Item的最大的边界,当Item中的内容大于边界的容量时,能容只会部分显示。


void QGraphicsItem::paint()是在程序一开始就会直接调用,完成初始化的操作,不需要信号和槽的支持,可以理解为自动事件吧。。。。。

paint()为虚函数。


在本程序中的subclass中使用如下:


void NewItem::paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget )
{
QPen pen(Qt::darkBlue);
if(option->state&QStyle::State_Selected)//画的时候,State_Selected——Used to indicate if a widget is selected.
{									//被选择时
pen.setStyle(Qt::DotLine);
pen.setWidth(2);
}
painter->setPen(pen);
painter->setBrush(Qt::white);
QRectF rect(x,y,45,30);
painter->drawRoundedRect(rect,rect.width()/2.0,rect.height()/2.0);


painter->setPen(Qt::darkGreen);
painter->drawText(rect,Qt::AlignCenter,text);
}


2、设置Item的几何位置。


方法一、通过paint()中的代码:

QRectF rect(x,y,45,30);
painter->drawRoundedRect(rect,rect.width()/2.0,rect.height()/2.0);


方法二、可以重载子类构造函数,用参数决定Item的位置:

NewItem::NewItem(qreal a,qreal b)
{
setFlags(ItemIsMovable|ItemIsSelectable);
x=a;
y=b;
text="text1";
}


3、另附好用的InputDialog:


QInputDialog inputdialog;
bool OK;
QString tmptext;
QString gettext=inputdialog.getText(event->widget(),"Edit Text","Enter new text:",QLineEdit::Normal,tmptext,&OK);
if(OK&&!text.isEmpty())//QInputDialog 好用!!!!!!!!!!!!!!!
{
text=gettext;
prepareGeometryChange();//大小、形状改变时调用
}





4、通过选项改变Item里面的数据



联系上文:当使用update()和prepareGeometryChange()是要调用:paint();故在paint()函数中设置传递变量就可以了:

painter->drawText(rect,Qt::AlignCenter,text);



5、菜单类



a)先设置动作,再创建菜单


b)菜单栏和工具栏的位置怎么弄???


1.菜单栏创建 

直接使用 QMainWindow::menuBar()函数即可返回一个QMenuBar指针;


2.工具栏 

定义了QToolBar *toolbar之后,不用new分配空间,直接用toolbar=addToolBar(" &New")


newaction->setIcon(QIcon("00.jpg"));   插入图片时别改图片的格式


6、图形化菜单



setIconSize(QSize())设置图标的大小。。




7、连线两个NewItem(画条直线)



QGraphicsItem::pos()返回的是Item的左上坐标。

具体的实现函数:

void lineItem::trackNodes()
{
QPoint f1(one->pos().x()+15,one->pos().y()+20);
QPoint f2(two->pos().x()+15,two->pos().y()+20);
setLine(QLineF(f1,f2));
}





8、数据存取


a)存 NewItem的 位置大小和文本以及lineItem的位置 即可


b)再读取,就可以恢复原状态


bool DiagramWindow::read()
{
QFile file("Graphics");
if(!file.open(QIODevice::ReadOnly)){
QMessageBox::warning(this,tr("QGraphhics"),tr("Cannot read file %1:\n%2.")
.arg(file.fileName()).arg(file.errorString()));
return false;
}
QDataStream in(&file);
in.setVersion(QDataStream::Qt_5_2);
quint32 magic;
in>>magic;
if(magic!=MagicNumber){
QMessageBox::warning(this,tr("QGraphics"),tr("The file is not a Spreadsheet file"));
return false;
}
qreal x;
qreal y;
while(!in.atEnd())
{
in>>x>>y;
NewItem *newitem=new NewItem(x,y);
newitem->setSelected(true);
scene->addItem(newitem);
view->setScene(scene);
update();
}
QApplication::restoreOverrideCursor();
return true;
}

bool DiagramWindow::save()
{
QFile file("Graphics");
if(!file.open(QIODevice::WriteOnly)){
QMessageBox::warning(this,"Graphics",tr("Cannot write file %1:\n%2.").arg(file.fileName())
.arg(file.errorString()));
return false;
} 
QDataStream out(&file);
out.setVersion(QDataStream::Qt_5_2);
out<<quint32(MagicNumber);
QApplication::setOverrideCursor(Qt::WaitCursor);
QList<QGraphicsItem*>items=scene->items();
QMutableListIterator<QGraphicsItem*>i(items);
QGraphicsItem*tmp;
while(i.hasNext())
{
tmp=i.next();
out<<qreal(tmp->pos().x())<<qreal(tmp->pos().y());
}
QApplication::restoreOverrideCursor();
return true;
}



(注:不能直接把QGraphicsItem或者其subclass作为基本类型传递,但可以把相关数据,如位置,文本,等通过变量存取。)

新注:都可以传递,只要能够让函数获取所需数据的正确地址,传递什么类型的数据都不要紧——20170626


9、改变系统图标。。。改rc文件:


IDI_ICON1               ICON                    "1.ico"
这是ICON                格式                     名称


10、改变左上坐标this->setWindowIcon().

有参数的的构造函数的功能之一:
NewItem::NewItem(qreal a,qreal b)  
为了传递参数。。。。。。
重新构造相应的NewItem,也就是有利于整个程序的信息交流。。。。。



11、坐标系的问题。

几何形状发生改变时,会发出resizeEvent这个事件设置resizeEvent();并写入以下内容即可:

void DiagramWindow::resizeEvent(QResizeEvent * event)
{
scene->setSceneRect(0,0,this->width(),this->height());

}



12、设置快捷键


delitem->setShortcut(Qt::Key_Delete);



13、error LNK2019: 无法解析的外部符号 "private: void __thiscall DiagramWindow::deleteitem(void)" (?deleteitem@DiagramWindow@@AAEXXZ),
该符号在函数 "private: static void __cdecl DiagramWindow::qt_static_metacall(class QObject *,enum QMetaObject::Call,int,void * *)" (?qt_static_metacall@DiagramWindow@@CAXPAVQObject@@W4Call@QMetaObject@@HPAPAX@Z) 中被引用


这种错误是由于  函数只有声明没有定义造成的。



14、最后得到如下视图的图形界面程序QGraphics1.0(有新建,连线,保存,删除,读取等功能)




再将之前的定时器结合在一起:




*总之问题还有很多,希望以后能够尽力做到2.0,3.0,4.0吧,以下是问题:


1、如何自己实现Items的选择和移动?

2、如何提高图标的清晰度?


3、资源管理相关知识是啥??

4、生成的EXE文件拖到桌面启动,无法工具栏的图标是怎么回事??


5、QGraphicsScene/View 的图层问题。

6、当QGraphicsScene的窗口大小变化时,怎么改变它的boundingrect()(可能没有??)使得已有的Items能够在
超出预设的范围scene=new QGraphicsScene(0,0,600,500)保存并读取其位置?以及如何当窗口大小改变时,如何
改变已有的Items的坐标和新生成的Items的坐标,即scene坐标系的0点永远在左上.(resizeEvent() 在QMainwindow
的subclass中能够被继承。)

void DiagramWindow::resizeEvent(QResizeEvent * event)
{
scene->setSceneRect(0,0,this->width(),this->height());
jishiqi->setGeometry(this->width()-130,this->height()-178,100,220);

};//这个可以解决问题6.

好了总结到此,希望以后做本职工作也要好好地努力,加油!!!

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值