qt 使用笔记
- [33ddd](### 窗口分割器使用)
窗口分割器使用
// 测试窗口分割 splitter
QDialog* pDlg = new QDialog();
QSplitter* splitterMain = new QSplitter(Qt::Horizontal,pDlg);
//splitterMain->setFixedSize(100,200);
splitterMain->setStretchFactor(1, 1);
QTextEdit* textLeft = new QTextEdit(tr("左侧窗口"), splitterMain);
QTextEdit* textRight = new QTextEdit(tr("右侧窗口"), splitterMain);
if (pDlg->exec())
{
}
delete textLeft;
delete textRight;
delete splitterMain;
delete pDlg;
鼠标测量两点间角度
void QAPView::mousePressEvent(QMouseEvent* event)
{
QPointF point = mapToScene(event->pos());
CPose pos = MapSenceCoord2Pose(point);
emit GrpahicsViewMouseMove(point, pos);
QPointF ptScene = point;
if (rightKeyPressed)
{
m_angleToolEndPoint = ptScene ;
if (m_pAngleLine == nullptr)
{
m_pAngleLine = new QGraphicsLineItem();
}
if (m_pArrow1 == nullptr)
m_pArrow1 = new QGraphicsLineItem();
if (m_pArrow2 == nullptr)
m_pArrow2 = new QGraphicsLineItem();
if (m_pAngleText == nullptr)
m_pAngleText = new QGraphicsTextItem();
QLineF lineAngle = QLineF(m_angleToolStartPoint, m_angleToolEndPoint);
// 直线太短不显示
if (qAbs(lineAngle.dy()) < 2 || qAbs(lineAngle.dx()) < 2)
return;
m_pAngleLine->setLine(lineAngle);
QPen penLine(Qt::red, 3, Qt::SolidLine);
m_pAngleLine->setPen(penLine);
m_pScene->addItem(m_pAngleLine);
// 直线角度
double angle_line = atan2(lineAngle.dy(), lineAngle.dx());
qreal arrowSize = 20;
qreal arrowAng = 15 / 180.0 * PI;
QPointF arrowP1 = lineAngle.p2() + QPointF(sin(-angle_line + arrowAng - PI / 2) * arrowSize, cos(-angle_line + arrowAng - PI / 2) * arrowSize);
QPointF arrowP2 = lineAngle.p2() + QPointF(sin(-angle_line - arrowAng - PI / 2) * arrowSize, cos(-angle_line - arrowAng - PI / 2) * arrowSize);
m_pArrow1->setLine(QLineF(lineAngle.p2(), arrowP1));
m_pArrow2->setLine(QLineF(lineAngle.p2(), arrowP2));
m_pArrow1->setPen(penLine);
m_pArrow2->setPen(penLine);
m_pScene->addItem(m_pArrow1);
m_pScene->addItem(m_pArrow2);
m_pArrow1->setVisible(true);
m_pArrow2->setVisible(true);
/// 角度值显示
//m_pAngleText->setPlainText(QString::number(angle_line/PI*180));
//m_pAngleText->setDefaultTextColor(Qt::red);
double lineLen = lineAngle.length()*zoomRate* m_szImagePixel.width/1000.; // 像素数x放大倍率x每个像素的size
QString info = "<h3 style=\"color:#f33b45;\">" + QString("Length:%1 ,Angle:").arg(lineLen) + QString::number(angle_line / PI * 180) + "</h3>";
m_pAngleText->setHtml(info);
m_pAngleText->setPos(ptScene);
m_pScene->addItem(m_pAngleText);
}
}
隐藏tabwidget中的某些tab页面
// 方法1:
// 注意:::以下两行remove顺序由大到小否则不生效
//ui->tabWidgetTeachOther->removeTab(2);
//ui->tabWidgetTeachOther->removeTab(1);
// 方法2:
ui->tabWidgetTeachOther->setTabEnabled(1, false);
ui->tabWidgetTeachOther->setTabEnabled(2, false);
ui->tabWidgetTeachOther->setStyleSheet("QTabBar::tab:disabled {width: 0; color: transparent;}");
记录qt中库使用方法
tabBar竖向时文字横向
#include <QPainter>
#include <QProxyStyle>
#include <QStyleOptionTab>
#include <QRect>
#include <QSize>
class CustomTabStyle : public QProxyStyle
{
public:
QSize sizeFromContents(ContentsType type, const QStyleOption* option,
const QSize& size, const QWidget* widget) const
{
QSize s = QProxyStyle::sizeFromContents(type, option, size, widget);
if (type == QStyle::CT_TabBarTab) {
s.transpose();
s.rwidth() = 100; // 设置每个tabBar中item的大小
s.rheight() = 48;
}
return s;
}
void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const
{
if (element == CE_TabBarTabLabel) {
if (const QStyleOptionTab* tab = qstyleoption_cast<const QStyleOptionTab*>(option)) {
QRect allRect = tab->rect;
allRect.setWidth(allRect.width() - 5);
allRect.setHeight(allRect.height() - 2);
//选中状态
if (tab->state & QStyle::State_Selected) {
//save用以保护坐标,restore用来退出状态
painter->save();
painter->setBrush(QBrush(QColor((89, 150, 255,1))));
//矩形
//painter->drawRect(allRect.adjusted(0, 0, 0, 0));
//带有弧线矩形
painter->drawRoundedRect(tab->rect, 8, 8);
painter->restore();
}
//hover状态
else if (tab->state & QStyle::State_MouseOver) {
painter->save();
//painter->setBrush(QBrush(0x004ea1));
painter->drawRoundedRect(allRect, 8, 8);
painter->restore();
}
else {
painter->save();
//painter->setBrush(QBrush(0x78aadc));
painter->drawRoundedRect(allRect, 8, 8);
painter->restore();
}
QTextOption option;
option.setAlignment(Qt::AlignCenter);
painter->setFont(QFont("楷体", 12, QFont::Bold));
painter->setPen(0xffffff);
painter->drawText(allRect, tab->text, option);
return;
}
}
if (element == CE_TabBarTab) {
QProxyStyle::drawControl(element, option, painter, widget);
}
}
};
// =======================================
// 使用时
ui->tabWidget->setTabPosition(QTabWidget::West);//QTabWidget竖向
ui->tabWidget->tabBar()->setStyle(new CustomTabStyle);//注意,设置上述代码风格 就可以实现QTabBar横向
非UI cpp中使用信号槽
- 两个类必须继承于
QObject
,同时添加Q_OBJECT
。 QObject::connect()
举例: 非ui主函数中关联两个ui
QObject::connect(pDlg, &QCeC::sig_getFCenter, pTable, &QuiVn::on_sendFCenter);
- 当前cpp中要加入使用的类声明
-------可能会出现的报错举例-------
- QT的时候遇到这样一个问题, 简单来说就是一个需要使用信号和槽机制的子类在继承父类并添加 Q_OBJECT 宏之后报这样的错误: ‘staticMetaObject’ is not a member of ‘Manager’
**解决方法:要自定义信号和槽的话首先你这个类要是一个QObject的子类, 如果需要多继承要将 QObject 放在前面, 同时, 还需要在类声明的开始使用 Q_OBJECT 宏 ** - connect时如果控件使用了提升类,则需要把对象转换为提升类的指针
示例:QObject::connect(pDlg, &QTableDlg::send_MVParam, (QJsonTreeBrowser*)CCMain::GetInstance()->GetMainWin()->GetJsonTree(), &QJsonTreeBrowser::getVisionParams);
其中CCMain::GetInstance()->GetMainWin()->GetJsonTree()
返回QWidget*
,而传递信号时需要将其转换为QJsonTreeBrowser*
.
// 错误示范
class Controller :
public AbstractClass, public QObject
{
...
//正确示范
class Controller :
public QObject, public AbstractClass // QObject 写在前面
{
...
}
定时器使用
#include <QTimer>
timer = new QTimer(this);
timer->setInterval(100); // 定时间隔
connect(timer, SIGNAL(timeout()), this, SLOT(saveImage())); // 信号槽绑定定时函数
// 打开、关闭定时器
timer->start();
timer->stop();
抓取屏幕/指定窗口
QScreen* screen = QApplication::primaryScreen();
QRect rectGif(0, 0, 1000, 900);
// grabWindow 第一个参数是UI窗口控件的id
//QPixmap pix = screen->grabWindow(ui.tab_vision->winId(), ui.tab_vision->x() + rectGif.x(), ui.tab_vision->y() + rectGif.y(), rectGif.width(), rectGif.height());
QPixmap pix = screen->grabWindow(0);//QApplication::desktop()->winId());
QImage image = pix.toImage().convertToFormat(QImage::Format_RGB888);
cv::Mat scr = QImageToCvMat(image);
on_displayImage(scr);
抓取其它应用程序窗口:
//通过spy++.exe 获取(C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\Tools)
#include "WinUser.h"
QString windowname = "WeChat";
QString classname = "Qt5QWindowIcon";
HWND hwnd = FindWindow((LPCWSTR)classname.unicode(), (LPCWSTR)windowname.unicode());//查找窗口句柄
//QString name = "TaskManagerWindow";
//HWND hwnd = FindWindow((LPCWSTR)name.unicode(), L"任务管理器");
//ShowWindow(hwnd, SW_RESTORE);//激活并置顶窗口,ShowWindow里面的参数可以网上搜一下,不同功能不同参数。
QPixmap pix = screen->grabWindow(WId(hwnd)); // WId 获取窗口id
嵌入外部程序窗口进入qt
// 注:有些程序窗口可能会嵌入失败
// 文件管理器嵌入
QString clsname = "CabinetWClass";
QString winname = QStringLiteral("文件资源管理器");
HWND hwnd = FindWindow((LPCWSTR)clsname.unicode(), (LPCWSTR)winname.unicode());
QWindow* pmang = QWindow::fromWinId((WId)hwnd);
//pmang->setFlags(pmang->flags() | Qt::CustomizeWindowHint | Qt::WindowTitleHint);
QWidget* xemb = QWidget::createWindowContainer(pmang, ui.tab_testFilter, Qt::FramelessWindowHint);
xemb->setMinimumSize(900, 800);
QToolBar 如何添加动作图标
需要先在右下角的动作编辑器添加动作,然后将动作选中拖动至ToolBar控件栏 即可
参考 https://blog.csdn.net/Littlehero_121/article/details/129240276
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App