Qt入门记录

5 篇文章 0 订阅

近期毕设需要使用图形化界面,想要尝试Qt。

安装配置

Windows7系统,VS2013, 官网上下载了Qt5.5.1版本,没敢用最新的。

具体为qt-opensource-windows-x86-msvc2013_64-5.5.1,VS插件下载了qt-vs-addin-1.2.5。

(官网归档 http://download.qt.io/archive/


安装过程比较顺利,大小一共2G+。

打开VS,点击选项栏QT5下的Qt Options,添加Qt安装目录(比如E:\programs_store\Qt\5.5\msvc2013_64)为路径。

之后新建Qt项目,可以发现include都起了红线,右键项目属性,给配置属性>C/C++>常规>附加包含目录加上Include,以为为例,路径为E:\programs_store\Qt\5.5\msvc2013_64\include。


以HelloWorld作为测试。

此刻的我对Qt框架一无所知,先照葫芦画瓢,include一下QLabel,然后

	QLabel label("Hello,world");
	label.show();

编译,成功,运行,成功。哇,意外地顺利,以为会遇到花式报错来着。

那么下面开始了解Qt的框架,学习资料为https://www.devbean.net/2012/08/qt-study-road-2-catelog/

与OpenCV结合

在初步了解Qt之后,我将先前的项目文件(.h, .cpp)先加入了新建的Qt项目,接着需要配置OpenCV。此处遇到了困难,在教程中,VS+Qt+OpenCV的组合里,配置OpenCV的过程和普通VS项目相同,而当我加入事先保存好的项目属性表时,编译出现很多错误,都是ERROR LNK 2001,无法解析的外部符号。


查询LNK 2001错误的可能原因,这篇文章有整理一些 https://blog.csdn.net/djinglan/article/details/6682193

梳理一遍自己的环境,

VS2013, Qt5.5.1_msvc2013_64, OpenCV 2.4.13,并且在配置文件里使用的是x86,VS项目调试模式为Debug-x64

会不会是x64和x86的区别呢?

那么更新OpenCV相关的属性,全部更换成x64试一试。

首先电脑的环境变量-系统变量,PATH加入x64的bin路径;

接着修改项目属性表,老三样,1)VC++目录>包含目录,2)VC++目录>库目录,3)链接器>输入>附加依赖项

因为更新了系统变量,重启试试。

重启之后编译程序,顺利通过!

MainWindow布局

参考网上教程(大多直接在main里写)和官方BasicLayouts示例(是QDialogue类)进行布局测试,发现怎么也显示不出正常的效果,menuBar不显示,一片空白,或者label堆叠在一起,没有起到layout的作用……令人烦躁。

查询到:Note: Creating a main window without a central widget is not supported. You must have a central widget even if it is just a placeholder.

这可能是关键。新建项目时自动生成的是继承于QMainWindow的,所以应该先新建一个widget再进行布局。

main函数是很简洁的show这个MainWindow类,具体的编辑就在类里了。

我的窗体总体为水平布局,最左边是一张图,中间是三个竖列的按钮,最右边是另一张图,所以是水平-竖直的嵌套。

以下是.h文件:

#ifndef SKELETONCORRECTION_H
#define SKELETONCORRECTION_H
//主界面
#include <QtWidgets/QMainWindow>
#include "ui_skeletoncorrection.h"

QT_BEGIN_NAMESPACE
class QAction;
class QLabel;
class QGroupBox;
class QMenu;
class QMenuBar;
class QPushButton;
QT_END_NAMESPACE

class SkeletonCorrection : public QMainWindow
{
	Q_OBJECT

public:
	SkeletonCorrection(QWidget *parent = 0);
	~SkeletonCorrection();

	void createMenu();
	void createLabels();
	void createButtons();

private:
	QWidget* cenWidget;

	QLabel *lLabel, *rLabel;
	QPushButton *btn_Root;
	QPushButton *btn_Correction;
	QPushButton *btn_Save;

	QVBoxLayout *verBtnLayout;

	QMenuBar *menuBar;
	QMenu *fileMenu;

	
};

#endif // SKELETONCORRECTION_H

以下是.cpp文件:

#include "skeletoncorrection.h"
#include <qaction.h>
#include <qmenubar.h>
#include <qmessagebox.h>
#include <qstatusbar.h>
#include <qtoolbar.h>
#include <qlabel.h>
#include <qpushbutton.h>


SkeletonCorrection::SkeletonCorrection(QWidget *parent)
	: QMainWindow(parent)
{
	cenWidget = new QWidget(this);//point to QMainWindow
	setCentralWidget(cenWidget);

	createMenu();//尚未实现
	createLabels();
	createButtons();

	QHBoxLayout *mainLayout = new QHBoxLayout(cenWidget);//主要布局,指定parent为cenWidget

	mainLayout->addWidget(lLabel);

	verBtnLayout = new QVBoxLayout;//嵌套布局,竖直
	verBtnLayout->addWidget(btn_Root);
	verBtnLayout->addWidget(btn_Correction);
	verBtnLayout->addWidget(btn_Save);

	mainLayout->addLayout(verBtnLayout);

	mainLayout->addWidget(rLabel);


	setWindowTitle(tr("Skeleton Correction"));

}

SkeletonCorrection::~SkeletonCorrection()
{

}


void SkeletonCorrection::createMenu(){

}
void SkeletonCorrection::createLabels(){
	lLabel = new QLabel(tr("Left"));
	rLabel = new QLabel(tr("Right"));

}
void SkeletonCorrection::createButtons(){
	btn_Root= new QPushButton(tr("Set Root Point"));
	btn_Correction = new QPushButton(tr("Auto Correction"));
	btn_Save = new QPushButton(tr("Save to Local Disk"));
}

运行结果:


符合期望。

因为这个widget的缘故耗费了一两天……前途堪忧。

菜单栏

加入菜单栏,一开始是新建了MenuBar对象,将这个对象加入到cenWidget,发现长度很短,不能撑起整条,设置parent为this也是一样。后来不新建对象,使用MainWindow类自带的MenuBar(),就OK了……

void SkeletonCorrection::createMenu(){
	openAction = new QAction(tr("&Open..."), this);
	openAction->setShortcuts(QKeySequence::Open);
	connect(openAction, &QAction::triggered, this, &SkeletonCorrection::open);

	//menuBar = new QMenuBar(cenWidget);
	//fileMenu = menuBar->addMenu(tr("&File"));
	fileMenu = menuBar()->addMenu(tr("&File"));
	fileMenu->addAction(openAction);
}

另外设置了一下margin,所以边缘多了些空白。

显示图片

利用QLabel来显示图片。

首先,设置菜单动作,打开本地图片,测试输出路径。

void SkeletonCorrection::createMenu(){
	//set action
	fileOpenAction = new QAction(tr("&Open..."), this);
	fileOpenAction->setShortcuts(QKeySequence::Open);
	connect(fileOpenAction, SIGNAL(triggered()), this, SLOT(fileOpenActionSlot()));
	

	//set menu
	fileMenu = menuBar()->addMenu(tr("&File"));
	fileMenu->addAction(fileOpenAction);
}
void SkeletonCorrection::createContextMenu(){
	this->addAction(fileOpenAction);
	this->setContextMenuPolicy(Qt::ActionsContextMenu);
}

void SkeletonCorrection::fileOpenActionSlot(){
	selectFile();
}

void SkeletonCorrection::selectFile(){
	QFileDialog *fileDialog = new QFileDialog(this);
	fileDialog->setWindowTitle(tr("Open Image"));
	fileDialog->setDirectory(".");
	fileDialog->setNameFilter(tr("Images(*.png *.jpg *.jpeg *.bmp"));
	fileDialog->setViewMode(QFileDialog::Detail);

	QStringList fileName;
	if (fileDialog->exec()){
		fileName = fileDialog->selectedFiles();
        	hasSrcImg = true;//布尔变量
	}
	for (auto tmp : fileName){
		qDebug() << tmp << endl;
		srcImg = imread(tmp.toLatin1().data());
	}
	updateLeftLabel();//更新左边标签,显示原图像
}

可以在输出处看到图片路径被正确输出了。之后是显示图片。

在selectFile函数末尾调用updateLeftLavel函数更新lLabel, 类新建Mat类型成员变量srcImg来保存图片。显示时,先转换为QImage再进行处理。

void SkeletonCorrection::updateLeftLabel(){

	cvtColor(srcImg, srcImg, CV_RGB2RGBA);
	QImage qImg = QImage((const unsigned char*)(srcImg.data), srcImg.cols, srcImg.rows, QImage::Format_RGB32);
	lLabel->setPixmap(QPixmap::fromImage(qImg));
	lLabel->resize(lLabel->pixmap()->size());

}

可以在label中显示图片了。

PushButton点击事件

对于事件的理解,可以参见这篇文章

点击按钮,触发一些动作,最简单的就是利用信号与信号槽。

	//.h文件中
private slots:
	ointSlot();//设置根关节点(颈部)按钮的槽函数
	void autoCorrectionSlot();//自动纠正按钮的槽函数
//.cpp文件中
void SkeletonCorrection::createButtons(){
	btn_Root= new QPushButton(tr("Set Root Point"));
	btn_Correction = new QPushButton(tr("Auto Correction"));
	btn_Save = new QPushButton(tr("Save to Local Disk"));
        //创建button时,用connect函数将按钮与槽函数联系起来
	connect(btn_Root, SIGNAL(clicked()), this, SLOT(setRootPointSlot()));
	connect(btn_Correction, SIGNAL(clicked()), this, SLOT(autoCorrectionSlot()));

}

之后再槽函数里具体编写功能即可。

另一种情况是使用MouseEvent,点击鼠标时,想要有针对性地实现一些功能。那么就要在类成员函数里对对应的鼠标事件函数进行重载,比如我想要在鼠标release时实现一些功能。

//.h
protected:
	void mouseReleaseEvent(QMouseEvent *e);//鼠标释放事件

//.cpp
void SkeletonCorrection::mouseReleaseEvent(QMouseEvent *e){
		QPoint curPos = e->pos() - (cenWidget->pos() + lLabel->pos());
		qDebug() << "mouse release position " << curPos.x() << " " << curPos.y() << endl;
}

我想要获取鼠标在一个label中的相对位置,根据这篇文章所说,结果正确。

我所需要的基本功能就是这样,之后就添加一些messageBox之类,微调。


以上。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值