Qt 简单截图工具(二) 添加菜单栏,添加取色器、切图功能

发布于:2022-11-16 ⋅ 阅读:(626) ⋅ 点赞:(0)


本系列目录

Qt 简单截图工具(一) 高仿QQ截屏 滑动截屏
Qt 简单截图工具(二) 添加菜单栏,添加取色器、切图功能


前言

Qt 简单截图工具(一) 中实现了滑动截屏的功能,一些截屏的操作使用快捷键相应,但是在没有操作说明的情况下还是添加图形化菜单栏对用户更加友好,所以本文将围绕之前的功能添加菜单栏,增加保存截屏文件、取色器、切图这些功能。


实现效果图如下:
菜单栏效果图

菜单栏效果图

切图效果图

切图功能效果图

样式表的应用,资源文件的添加可以参考 Qt 下拉复选框(MultiSelectComboBox)(二) 样式表设置,本文不再对这方面进行讲解。

一、菜单栏

本节将从菜单栏的构思、实现、存在问题这三个方向去讲解

1.如何实现

对于菜单栏的添加一开始主要有两个实现方向:

  1. 使用画笔直接绘制菜单栏,这种方式界面效果容易实现,但是具体功能与界面的绑定比较麻烦,而且如果想要菜单栏美观的话,还需要绘制按钮的三态(常态、悬浮、按下),绘制三态就又不得不计算绘制按钮的位置,综上所述此方法界面效果的实现比较灵活,但是具体功能的实现比较麻烦。
  2. 新建一个QWidget对象当作菜单栏,其中设置水平布局存放按钮,通过move()函数控制其紧贴截屏区域显示。这种方式具体功能只需要给每个按钮绑定相应的槽函数即可,但是样式的绘制就被局限在QPushButton类对象内。考虑到本次菜单栏对样式的需求并没有那么阴间,相比之下方法二为最优解。

2.实现步骤

  1. 创建一个QWidget对象tool_bar_ ,tool_bar_ 设置水平布局,水平布局中添加按钮对象(QPushButton)。
  2. 设置布局 边距、内边距、按钮样式等。
  3. 按钮绑定相应功能槽函数。
  4. tool_bar_ 弹出位置为截屏矩形区域下方(这里不做边缘条件处理,感兴趣的小伙伴可以去实现一下)

代码示例如下:

void CustomSlidScreenCapture::ShowToolBar(bool _flag)
{
	if (_flag)
	{
		QPoint tool_bar_move(mouse_slid_end_point_.x() - tool_bar_->width(), mouse_slid_end_point_.y() + 10);
		tool_bar_->move(tool_bar_move);
		tool_bar_->show();
	}
	else
	{
		tool_bar_->hide();
	}
	this->update();
	
}
  1. 菜单栏只有在矩形区域确定时显示,滑动截屏过程中,二次处理截屏图片时不显示菜单栏。这部分主要是逻辑的判断,相应条件调用上文ShowToolBar(bool)接口即可,这里不加赘述。

3.样式设置

1.样式表设置

菜单栏整体风格为白色,具体代码如下:

/************************************CustomSlidScreenCapture***********************************/

 /************************************CustomSlidScreenCapture菜单栏主体样式***********************************/
QWidget#screen_capture_toolbar
{
    background-color:rgb(255,255,255);
}
  /************************************CustomSlidScreenCapture菜单栏按钮总体样式***********************************/
QPushButton#screen_capture_toolbar_copy, QPushButton#screen_capture_toolbar_color
, QPushButton#screen_capture_toolbar_cute, QPushButton#screen_capture_toolbar_save
, QPushButton#screen_capture_toolbar_result, QPushButton#screen_capture_toolbar_close
{
    background-color:rgb(255,255,255);
    border:none;
}
QPushButton#screen_capture_toolbar_copy:hover, QPushButton#screen_capture_toolbar_color:hover
, QPushButton#screen_capture_toolbar_cute:hover, QPushButton#screen_capture_toolbar_save:hover
, QPushButton#screen_capture_toolbar_result:hover, QPushButton#screen_capture_toolbar_close:hover
{
    background-color:rgb(211,211,211);
    border:none;
}
QPushButton#screen_capture_toolbar_copy:pressed, QPushButton#screen_capture_toolbar_color:pressed
, QPushButton#screen_capture_toolbar_cute:pressed, QPushButton#screen_capture_toolbar_save:pressed
, QPushButton#screen_capture_toolbar_result:pressed, QPushButton#screen_capture_toolbar_close:pressed
{
    background-color:rgb(255,255,255);
    border:none;
}
/************************************CustomSlidScreenCapture菜单栏按钮--copy***********************************/
QPushButton#screen_capture_toolbar_copy
{
    image:url(":/PracticeOne/Resources/copy.png");
}
/************************************CustomSlidScreenCapture菜单栏按钮--color***********************************/
QPushButton#screen_capture_toolbar_color
{
    image:url(":/PracticeOne/Resources/color.png");
}
/************************************CustomSlidScreenCapture菜单栏按钮--cute***********************************/
QPushButton#screen_capture_toolbar_cute
{
    image:url(":/PracticeOne/Resources/cute.png");
}
/************************************CustomSlidScreenCapture菜单栏按钮--save***********************************/
QPushButton#screen_capture_toolbar_save
{
    image:url(":/PracticeOne/Resources/save.png");
}
/************************************CustomSlidScreenCapture菜单栏按钮--result***********************************/
QPushButton#screen_capture_toolbar_result
{
    image:url(":/PracticeOne/Resources/result.png");
}
/************************************CustomSlidScreenCapture菜单栏按钮--close***********************************/
QPushButton#screen_capture_toolbar_close
{
    image:url(":/PracticeOne/Resources/close.png");
}
tool_bar_buttons.at(0)->setObjectName("screen_capture_toolbar_copy");
tool_bar_buttons.at(1)->setObjectName("screen_capture_toolbar_color");
tool_bar_buttons.at(2)->setObjectName("screen_capture_toolbar_cute");
tool_bar_buttons.at(3)->setObjectName("screen_capture_toolbar_save");
tool_bar_buttons.at(4)->setObjectName("screen_capture_toolbar_result");
tool_bar_buttons.at(5)->setObjectName("screen_capture_toolbar_close");

2.样式相关API设置

    for (int i = 0; i < tool_bar_buttons.size(); i++)
	{
		tool_bar_layout->addWidget(tool_bar_buttons.at(i));
		//设置菜单栏箭头样式
		tool_bar_buttons.at(i)->setCursor(Qt::ArrowCursor);
		tool_bar_buttons.at(i)->setFixedSize(40, 40);
	}


    tool_bar_->setObjectName("screen_capture_toolbar");
	//内边距
	tool_bar_layout->setContentsMargins(0, 0, 0, 0);
	//子控件间距
	tool_bar_layout->setSpacing(0);
	//隐藏标题栏
	tool_bar_->setWindowFlags(Qt::FramelessWindowHint);
	tool_bar_->hide();
	//设置窗口层次
	this->stackUnder(tool_bar_);

二、取色器

取色器功能在Qt 简单截图工具(一) 中已经讲解如何实现,这里只是对该功能进行完善,可以从菜单栏控制取色器的开关。添加全局标志位即可实现该功能,判断条件位置如下。

void CustomSlidScreenCapture::DrawInformationRect(QPainter *_painter)
{
	if (!color_is_show_)
	{
		return;
	}
}

不清楚接口含义的可以回顾文章一

三、切图

1.如何实现

  • 在使用了众多截屏插件后,发现切图功能共有两个分化:
方式 效果 优缺点
方式一 切图后,截屏未结束,还可以继续进行截屏,切图结果置顶显示,截屏结束时,切图关闭 可以对同一屏幕内容进行多次切图,方便对比
方式二 切图后,截屏结束,切图效果保留置顶显示 可以截取不同屏幕内容,并将切图内容保留,方便对不同屏幕内容进行操作

两种方式各有优缺点,这里实现方式一。

  • 切图功能就是将当前截屏结果独立显示,可以考虑new一个Qlabel对象,将QLabel对象show()出来。这种方式从一方面来讲,切图不可能只是一张图片,应该有其相应的操作,这个时候就需要有右键菜单来对切图对象进行操作,即每一个QLabel对象对于一个QMenu对象,另一方面,每个切图都可以鼠标拖动,这个就需要来判断当前点击的是哪个切图来进行移动,维护这些的代价太大,不容易实现,所以应该实现一个自定义的QDialog类,将这些操作都放在该类中,截屏类( CustomSlidScreenCapture) 只需要考虑如何去调用这类即可,不需要维护大量的QLabel、QMenu对象。

2.实现步骤

  1. 创建自定义QDialog类,切图使用画笔绘制到窗口上,窗口自适应切图大小。

具体代码如下:

void CutGraph::paintEvent(QPaintEvent *event)
{
	this->setFixedSize(pixmap_.size());
	QPainter *painter = new QPainter(this);
	painter->save();
	painter->drawPixmap(0, 0, pixmap_);										//将获取的图片画到窗体上
	painter->restore();
}
  1. 隐藏窗口标题,窗口设置置顶显示,因为切图结果要显示在截屏背景前
CutGraph::CutGraph(QWidget *parent /*= Q_NULLPTR*/)
{
	InitMenu();
    //隐藏标题、置顶显示
	this->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint);
	this->show();
}
  1. 添加菜单,窗口设置置顶显示会使切图的右键菜单(下文菜单对象统称为menu_)无法再次显示在切图前,所以menu_需要 随用随创 。如果menu_为全局唯一,那么在其第一次显示后(第一次显示因为是创建后第一次show,所以可以显示在切图前),后续显示都将显示在切图后,导致显示不全,所以要在显示前删掉原先menu_对象,创建新menu_对象。如果小伙伴有其他解决办法,欢迎留言,不胜感谢!
void CutGraph::mousePressEvent(QMouseEvent *event)
{
	if (event->button() == Qt::RightButton)
	{
		delete menu_;
		menu_ = new QMenu(this);
		menu_->setWindowFlags(Qt::Popup);
		for (auto menu_one : menu_action_)
			menu_->addAction(menu_one);
		menu_->move(event->globalPos());
		menu_->show();
	}
}
  1. 菜单绑定槽函数,复制、关闭、保存。
void CutGraph::CheckedCopyAction()
{
	QApplication::clipboard()->setPixmap(pixmap_);
}

void CutGraph::CheckedCloseAction()
{
	close();
}

void CutGraph::CheckedSaveAction()
{
	QString filename = QFileDialog::getSaveFileName(this, QStringLiteral("保存图片"), "", tr("*.bmp;; *.png;; *.jpg;; *.tif;; *.GIF"));;//选择路径
	if (filename.isEmpty())
		return;
	else
	{
		if (!(pixmap_.save(filename))) //保存图像
		{

			QMessageBox::information(this, QStringLiteral("图片保存"), QStringLiteral("截屏文件保存失败!"));
			return;
		}
		QMessageBox::information(this, QStringLiteral("图片保存"), QStringLiteral("截屏文件保存成功!"));
	}
}

  1. 添加鼠标拖动。

总结

本次优化,添加了一些截图软件的基本功能,代码实现较为简单,只将主要代码进行显示,有需要完整代码的可留言。

如果此文帮助到你( •̀ ω •́ )✧,动动小手点个赞可好O(∩_∩)O。

原创文章,转载请标明本文出处。

本文含有隐藏内容,请 开通VIP 后查看