北京营销型网站,文昌市住房和城乡建设局网站,如何网站做百度推广,优秀的企业网站设计目录 Qt 获取当前电脑桌面的路径Qt 获取当前程序运行路径Qt 创建新的文本文件txt#xff0c;并写入内容如何向QPlainTextEdit 写入内容QTimerQMessageBox的使用QLatin1StringQLayoutC在c头文件中写#include类的头文件与直接写class加类名有何区别mutable关键字前向声明 QFontQ… 目录 Qt 获取当前电脑桌面的路径Qt 获取当前程序运行路径Qt 创建新的文本文件txt并写入内容如何向QPlainTextEdit 写入内容QTimerQMessageBox的使用QLatin1StringQLayoutC在c头文件中写#include类的头文件与直接写class加类名有何区别mutable关键字前向声明 QFontQLabel设置QLabel字体的大小和颜色QLabel设置背景色字体超过QLabel长度如何以省略号的形式显示QLabel显示不完全怎么自动换行 如何为布局添加分割线Qlabel显示的链接可以点击打开获得界面当前点击的按钮qobject_castQDialogQDialog隐藏/删除标题栏QDialog 去掉问号只保留关闭 如何去掉按钮的虚线框QPushButton设置按钮的大小rgba(0,0,0,0)第四个参数详解QT实现弹窗后背景淡化geometry()与frameGeometry()的区别Qt属性系统Q_PROPERTYC 11 default和delete对象名获取类名如何在Qt中添加文件夹对左侧树的目录进行分类setStatusTip、setToolTip、setWhatsThis的区别Qt自定义的类需要继承QObject吗Qt 常见编译错误mainWindow工具栏调整icon的大小去除QComboBox中项中含有的省略号有两个工具栏怎样让一个工具栏靠右右对齐Qwidgetwidget绘制背景色widget设置边框鼠标点击其他地方使当前widget隐藏将窗口置于当前窗口之下如何获取父类的窗口 自定义数据类型Q_DECLARE_METATYPE()注册QFontMetrics函数计算给定字体的字符和字符串的大小。宏Q_ASSERT 编译常见错误error: static assertion failed: The slot requires more arguments than the signal provides. [ #define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)]error: No rule to make target xxx.png, needed by debug/qrc_resource.cpp. Stop.error: [debug/qrc_resource.cpp] Error 1error: field has incomplete typeerror: jump to case label [-fpermissive] case xxx: ^error: passing const ProjectTreeViewDelegate as this argument discards qualifiers [-fpermissive] drawTreeViewItem(painter, drawRect, modelData);^error: default argument given for parameter x oferror: static assertion failed: Signal and slot arguments are not compatible.error: invalid application of sizeof to incomplete type XXXVariableData: sizeOf sizeof(T)关于内联inline的 error: invalid use of incomplete type xxx槽函数的lambda错误 error: passing const VarBasicData as this argument discards qualifiers [-fpermissive][](const VarBasicData varinfo) { varData.basic varinfo; }); update()的作用QColor打印颜色的名称基本颜色 event: 设置鼠标进入和离开时的框架样式.pri中的INCLUDEPATH的作用只设置右上角的关闭按钮在break之前可以直接return吗switch中return后是否需要break多层for循环break只会跳出一层循环QTreeViewset属性设置setExpanded不展开的问题 迭代器怎么赋值使用*blockIter枚举的定义findChild的使用connectconnect写法connect的lambda表达式lambda中的值捕获[]与引用捕获[]发信号之前一定还要先建立连接connectconnect中嵌套connect注意重复连接connect的参数怎样避免connect重复连接信号槽连接 函数重载、参数不一致问题 Dialog鼠标在窗口外区域点击时关闭该窗口QModelIndex删除树的子节点QLineEdit当前坐标与全局坐标的转换判断当前焦点是否在某控件上Qt获得和失去焦点事件关于List的比较drag拖动如何显示拖动禁用的标志QFileDialogenum QFileDialog::AcceptModeenum QFileDialog::DialogLabel setFocus不生效的问题 Qt 获取当前电脑桌面的路径
#include QStandardPaths
QString desktop_path QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);Qt 获取当前程序运行路径
#include QCoreApplication//方法1
QString fileName QCoreApplication::applicationDirPath();//方法2
QString fileName QApplication::applicationDirPath();QCoreApplication 与 QApplication 的区别 QApplication 继承于 QGuiApplication而QGuiApplication 继承于 QCoreApplication QApplication 带GuiQCoreApplication 不带Gui
Qt 创建新的文本文件txt并写入内容
//在当前程序运行路径下创建
QFile file(QCoreApplication::applicationDirPath() /test.txt);
if (!file.exists()) {qDebug() 文件不存在;
}
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {qDebug() 文件打开失败;
}
QString str 测试文件是否被修改;
QTextStream out(file);
out str; //将str写入文件
file.close();如何向QPlainTextEdit 写入内容
void insertPlainText(const QString text);void appendPlainText(const QString text);QTimer
QTimer *timer new QTimer(this);
connect(timer, QTimer::timeout, this, MainWindow::slotRefresh());
timer-start(1000); //延迟1秒刷新QTimer还为单次触发定时器提供了一个静态函数。例如
QTimer::singleShot(200, this, MainWindow::slotRefresh());QMessageBox的使用
构造函数
QMessageBox messageBox(QMessageBox::Question, Question, The current project has been modified.\nDo you want to save it?, QMessageBox::Yes | QMessageBox::No);
messageBox.exec();通过构造函数和属性函数实现
QMessageBox messageBox(this);
messageBox.setIcon(QMessageBox::Warning);
messageBox.setWindowTitle(Warning);
messageBox.setText(Parsed file not found! Please reconfigure!);
messageBox.setStandardButtons(QMessageBox::Yes|QMessageBox::No);
messageBox.setDefaultButton(QMessageBox::Yes);
messageBox.exec();静态函数
QMessageBox::Information(this, Information, Project saved successfully!);QLatin1String
QLatin1String是const char* 的一层薄薄的封装。
许多QString的成员函数都用const char*代替QString作为参数实现重载。
例如假定str是QString对象
if (str auto || str extern|| str static || str register) {...
}上面的代码执行会比下面的代码执行快很多
if (str QString(auto) || str QString(extern)|| str QString(static) || str QString(register)) {...
}因为在第二部分的代码中会构造四个临时的QString对象并复制字符串中的值。
如果利用QLatin1String类来写上述的程序就是
if (str QLatin1String(auto)|| str QLatin1String(extern)|| str QLatin1String(static)|| str QLatin1String(register) {...
}虽然在代码输入的时候有点长但是它的执行效率和上面第一段的代码一样。
QLatin1String可以在任何需要QString对象的地方使用
QLabel label;
label.setObjectName(QLatin1String(111));QLayout
void QLayout::setContentsMargins(int left, int top, int right, int bottom)设置要围绕布局使用的左、上、右和下边距。 默认情况下QLayout使用样式提供的值。在大多数平台上所有方向的边距都是11像素。
QGridLayout* grid findChildQGridLayout*(gridLayout); //通过对象名获取布局
grid-setContentsMargins(10, 30, 50, 70); //上、左、右、下int spacing() const
void setSpacing(int)设置布局中小部件之间的间距 如果没有显式设置值则布局的间距继承自父布局或父小部件的样式设置。 对于QGridLayout和QFormLayout可以使用setHorizontalSpacing()和setVerticalSpacing()设置不同的水平和垂直间距。在这种情况下spacing()返回-1
C
在c头文件中写#include类的头文件与直接写class加类名有何区别
class 类名只是声明存在这么一个类但是通过这个声明无法得到任何关于此类的具体信息。这样你可以在其他使用到的地方声明一个该类型的指针。
#include xx.h在编译的时候把xx.h文件直接展开所以里面的接口都能用可以申明对象。但是class xx;这种方式就不会你只能使用它的指针或者引用你不能创建申明对象。
使用class 类名一般是为了去除编译依赖减少编译消耗的时间。 举个例子 有个头文件 “common.h”你在所有的头文件中都需要它所以都#include “common.h”当common.h中的代码有一些改动时你在运行代码时需要重新编译所有依赖它的头文件。而如果是Class Common当common.h中的代码一些改动时你在运行代码时当你之前编译过一次之后就不会再次编译所有依赖它的头文件。当一个文件头编译之后若这个头文件没有改动在下次运行代码时就不会重新编译
只声明类而不include可以降低各个文件编译时的关联度不会在改动了一下部分类的时候引发其他大量文件的重新编译在做小工程的时候没什么区别但是做大了编译一次需要好几个小时的时候这样做的优势就显现出来了。
mutable关键字
mutable也是为了突破const的限制而设置的。被mutable修饰的变量将永远处于可变的状态即使在一个const函数 中。
前向声明
在一个类的头文件当中声明一个类而不去定义它被称为前向声明。 在头文件中这个前向声明的类A是一个不完全类型incomplete type只知道类A的类型但不知道类A包含哪些成员。 不完全类型不能定义该类型的对象只能用于定义该类型的指针或者引用或者用于声明该类型作为参数或返回值的函数。 好处对于不必要的#include可以减少编译时间
// 当使用前向引用声明时只能使用被声明的符号而不能涉及类的任何细节。
class A; //前向声明类A
class B{
publicA* m_a; //用于定义指向这个类型的指针或引用void func(A a); //用于声明(不是定义)使用该类型作为形参或者返回类型的函数
}前向声明的类不能定义对象不知道类的大小及内部成员不能实例化。 可以用于定义指向这个类型的指针和引用即定义该类的指针或引用作为成员变量。 可以用于声明(不是定义)使用该类型作为形参或者返回类型的函数
QFont
QFont类用于绘制文本的字体。 注意在使用QFont之前必须存在一个QGuiApplication实例。可以使用QGuiApplication::setFont()设置应用程序的默认字体。 如果选择的字体不包含需要显示的所有字符QFont将尝试在最近的等效字体中找到字符。 当QPainter从字体中绘制字符时QFont将报告它是否具有该字符如果没有QPainter将绘制一个未填充的正方形。 常用构造函数
QFont(const QString family, int pointSize -1, int weight -1, bool italic false);
//参数说明字体样式、字体大小、字体粗细、是否斜体常用函数
void setFamily(const QString family) //设置字体样式void setPointSize(int pointSize) //设置字体大小 void setWeight(int weight) //设置字体粗细void setBold(bool enable) //设置字体是否加粗void setItalic(bool enable) //设置字体是否斜体void setPixelSize(int pixelSize) //设置字体像素大小void setOverline(bool enable) //设置字体上划线void setUnderline(bool enable) //设置字体下划线void setStrikeOut(bool enable) //设置字体删除线void setLetterSpacing(SpacingType type, qreal spacing);
//将字体的字母间距设置为spacing并将间距的类型设置为type。
//字母间距改变字体中单个字母之间的默认间距。根据所选择的间距类型字母之间的间距可以按字符宽度的百分比或按像素的百分比设置为更小或更大。enum QFont::SpacingType
枚举值描述QFont::PercentageSpacing0值为100将保持间距不变;值200将把字符后面的间距扩大到字符本身的宽度。QFont::AbsoluteSpacing1正值使字母间距增加相应的像素;负值会减小间距。
void setCapitalization(Capitalization caps);
//将此字体的文本的大写设置为大写。
//字体的大写使文本以选定的大写模式显示。enum QFont::Capitalization
枚举值描述QFont::MixedCase0正常的文本呈现选项其中不应用大小写更改。QFont::AllUppercase1全部大写QFont::AllLowercase2全部小写QFont::SmallCaps3小型大写意思是全部大写形式但其尺寸与对应小写字母的相同。QFont::Capitalize4首字母大写
QLabel
设置QLabel字体的大小和颜色
QLabel* label new QLabel(tr(test));
font.setFont(QFont(宋体), 12);QPalette pa;
pa.setColor(QPalette::WindowText, Qt::red);
font.setPalette(pa);QLabel设置背景色 QLabel* colorLabel new QLabel(this);colorLabel-setFixedSize(10, 10);QPalette palette colorLabel-palette();palette.setColor(QPalette::Background, Qt::black);colorLabel-setAutoFillBackground(true);colorLabel-setPalette(palette);字体超过QLabel长度如何以省略号的形式显示
QLabel* m_activeText new QLabel(this);
QString text abcdefg;
QFontMetrics fontWidth(m_activeText-font()); //计算字体的宽度
QString elideText fontWidth.elidedText(text, Qt::ElideMiddle, 80); //80为最大宽度
m_activeText-setText(elideText);QLabel显示不完全怎么自动换行
label-setWordWrap(true); // true自动换行
label-setAlignment(Qt::AlignVCenter); // 对齐方式如何为布局添加分割线
QLabel* lineLabel new QLabel(this);
lineLabel-setFrameStyle(QFrame::HLine | QFrame::Sunken); //Sunken:凹陷Raised凸起将lineLabel添加到布局即可
Qlabel显示的链接可以点击打开
label-setTextInteractionFlags(Qt::TextBrowserInteraction); //label中的内容可用鼠标选择文本复制链接激活
label-setOpenExternalLinks(true); //label中的内容若为链接可直接点击打开
label.setText(a href https://blog.csdn.net/WL0616?spm1000.2115.3001.5343点我试试); //https://blog.csdn.net/WL0616?spm1000.2115.3001.5343为链接网址获得界面当前点击的按钮 QPushButton* btn qobject_castQPushButton*(sender());qobject_cast
qobject_cast()函数的行为类似于标准c的dynamic_cast()其优点是不需要RTTI支持并且可以跨动态库边界工作。 qobject_cast动态转换QObject类的类型qobject_cast将括号中()的类型转换成尖括号中的类型。 T qobject_cast(QObject *object) 在使用时有两个限制
返回的T类型必须继承自QObject。在声明时必须有Q_OBJECT宏。
QLabel* label new QLabel();
QWidget* widget qobject_castQWidget*(label);QDialog
QDialog隐藏/删除标题栏
setWindowFlags(Qt::FramelessWindowHint);生成无边界窗口。用户不能通过窗口系统移动或调整无边界窗口的大小。
QDialog 去掉问号只保留关闭
Qt::WindowFlags flags Qt::Dialog;
flags | Qt::WindowCloseButtonHint;
setWindowFlags(flags);如何去掉按钮的虚线框
例如按钮有个focus的效果 如何取消这种效果
//方法1
setFocusPolicy(Qt::NoFocus);//方法2
setStyleSheet(outline: none); //方法3
setStyleSheet(padding: -1); QPushButton设置按钮的大小
QPushButton继承于QAbstractButtonQAbstractButton继承于QWidget下面其实是QWidget的接口
void setMinimumHeight(int minh)
void setMinimumSize(const QSize )
void setMinimumSize(int minw, int minh)
void setMinimumWidth(int minw)rgba(0,0,0,0)第四个参数详解
前三个参数表明颜色第四个参数表示透明度它的范围为0.0到1.0之间0.5为半透明。 rgba(0,0,0,1)则表示完全不透明的黑色 rgba(0,0,0,0.5)则表示半透明的看起来是灰色 rgba(0,0,0,0)则表示完全不透明的白色,也即是无色
QT实现弹窗后背景淡化
QWidget* widget new QWidget(this); widget-resize(this-width(), this-height()); widget-move(0, 0); widget-setStyleSheet(“background-color:rgba(0, 0, 0, 0.3);”); widget-show();
geometry()与frameGeometry()的区别
geometry()界面大小不包含窗口装饰器即标题栏 frameGeometry()界面大小包含上方的窗口装饰器即标题栏
Qt属性系统Q_PROPERTY
Qt提供了一个绝妙的属性系统Q_PROPERTY()是一个宏用来在一个类中声明一个属性property。 一个属性的行为就像一个类的数据成员但它有通过元对象系统访问的附加功能。
Q_PROPERTY(type name(READ getFunction [WRITE setFunction] |MEMBER memberName [(READ getFunction | WRITE setFunction)])[RESET resetFunction][NOTIFY notifySignal][REVISION int][DESIGNABLE bool][SCRIPTABLE bool][STORED bool][USER bool][CONSTANT][FINAL])属性例子 Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)Q_PROPERTY用于声明属性的宏Qt规定的 bool 属性类型 enabled 属性名称 READ isEnabled这两个单词可以放一起理解就是说可以通过 isEnabled去读属性值 WRITE setEnabled这两个单词可以放一起理解就是说可以通过 setEnabled去设置属性值
以上只是一个属性一个声明但是其实没有实现还需要分别是去实现isEnabled 和setEnabled这样整个属性才可以真正使用。
例子
class MaskWidget : public QDialog {Q_OBJECTQ_PROPERTY(QStringList names READ names WRITE setNames DESIGNABLE true)
public:static MaskWidget* instance();void setMainWidget(QWidget* pWidget);QStringList names() const;void setNames(const QStringList names);...
};属性提供的其他字段含义
READ用于读取属性值如果未指定成员变量通过MEMBER 则需要读取访问器函数。
WRITE写访问器函数是可选的。用于设置属性值。它必须返回void并且必须只接受一个参数要么是属性的类型要么是指向该类型的指针或引用。
MEMBER如果未指定读取访问器函数则需要成员变量关联。这使得给定的成员变量可读写而无需创建读写访问器函数。如果需要控制变量访问除了成员变量关联但不是两者之外还可以使用读或写访问器函数。
RESET复位功能是可选的。它用于将属性设置回其特定于上下文的默认值。
NOTIFY通知信号是可选的。如果已定义它应该指定该类中的一个现有信号该信号在属性值更改时发出。成员变量的通知信号必须采用零个或一个参数这些参数必须与属性的类型相同。参数将采用属性的新值。仅当属性确实发生更改时才应发出NOTIFY信号以避免绑定在QML中被不必要地重新计算。
REVISION修订号是可选的。如果包含它将定义属性及其通知程序信号以便在特定版本的API中使用通常用于暴露于QML。如果不包含则默认为0。
DESIGNABLE表示属性是否应该在GUI设计工具例如Qt Designer的属性编辑器中可见。大多数属性是可设计的默认为true。可以指定布尔成员函数而不是true或false。
SCRIPTABLE表示脚本引擎是否应该访问此属性默认为true。可以指定布尔成员函数而不是true或false。
STORED表示属性是应该被认为是独立存在还是依赖于其他值。它还指示在存储对象状态时是否必须保存属性值。
USER表示是将属性指定为类的面向用户属性还是用户可编辑属性。通常每个类只有一个用户属性默认值为false。
CONSTANT表示属性值是常量。对于给定的对象实例常量属性的READ方法每次调用时必须返回相同的值。对于对象的不同实例此常量值可能不同。常量属性不能有写入方法或通知信号。
FINAL表示派生类不会重写该属性。在某些情况下这可以用于性能优化但不是由moc强制执行的
C 11 default和delete
C11中当我们定义一个类的成员函数时如果后面使用delete去修饰那么就表示这个函数被定义为deleted也就意味着这个成员函数不能再被调用否则就会出错。 在C11之前当我们希望一个类不能被拷贝就会把构造函数定义为private但是在C11里就不需要这样做了只需要在构造函数后面加上delete来修饰下就可以了。
对象名获取类名
obj-metaObject()-className() QLatin1String(Dialog);如何在Qt中添加文件夹对左侧树的目录进行分类 在当前项目的路径中新建一个文件夹比如命名为src在新建的文件夹src里新建一个文本文档将其命名为src.pri将后缀名txt改为pri切换到Qt在当前项目工程的.pro中添加 include(src/src.pri)CtrlS保存保存后需要等个几秒就会显示你添加的文件夹在你添加的文件夹src里右击添加新文件就可以创建.h和.cpp文件
setStatusTip、setToolTip、setWhatsThis的区别
setStatusTip用于MainWindow的状态栏提示 setToolTip用于控件的提示 setWhatsThis用于Dialog上的帮助信息。
Qt自定义的类需要继承QObject吗
QObject类是所有Qt对象的基类。 自定义的类最好继承QObjectQ_OBJECT宏也是要写的。 便于使用信号与槽。
Qt 常见编译错误
error: ‘tr’ was not declared in this scope … tr() 是QObject类的成员函数。 原因自定义的类没有继承QObject
mainWindow工具栏调整icon的大小
toolBar-setIconSize(QSize(18,18));去除QComboBox中项中含有的省略号
当设置QComboBox的最大宽度时
combox-setMaximumWidth(100);如果项中的内容比较长此时就会出现在项的中间会出现省略号看起来不太美观 取消省略号的解决办法
combox-view()-setTextElideMode(Qt::ElideNone); //取消项中的省略号但是会导致看不见后面的字体enum TextElideMode {ElideLeft, //省略号在最左边ElideRight, //省略号在最右边ElideMiddle, //省略号在最中间ElideNone //无省略号};有两个工具栏怎样让一个工具栏靠右右对齐
再maintoolbar上设置一个widget将两个工具栏放到widget里面并用QHBoxLaout进行布局一个放到左边Qt::AlignLeft一个放到右边Qt::AlignRight两者之间再放一个弹簧即可。 在第一个工具栏里设置 QWidget* widget new QWidget(this);QComboBox* com1 new QComboBox(this);QComboBox* com2 new QComboBox(this);QToolBar* bar1 new QToolBar(widget);bar1-addWidget(com1);QToolBar* bar2 new QToolBar(widget);bar2-addWidget(com2);QHBoxLayout* lay new QHBoxLayout;lay-addWidget(bar1, Qt::AlignLeft);lay-addStretch();lay-addWidget(bar2, Qt::AlignRight);widget-setLayout(lay);ui-mainToolBar-addWidget(widget);Qwidget
widget绘制背景色
//CustomLabel继承与QLabel
void CustomLabel::setBackgroundColor(const QColor color) {QPalette palette;palette.setColor(QPalette::Background, color);setAutoFillBackground(true);setPalette(palette);
}widget设置边框
/*** brief paintEvent: 绘制边框*/
void ProjectTree::paintEvent(QPaintEvent* event) {Q_UNUSED(event)QPainter p(this);p.setPen(Qt::black); //设置画笔记颜色p.drawRect(0, 0, width() - 1, height() - 1); //绘制边框
}鼠标点击其他地方使当前widget隐藏
setWindowFlags(Qt::Popup);将窗口置于当前窗口之下
void QWidget::stackUnder(QWidget *w)将小部件放置在父小部件堆栈的w下。要做到这一点小部件本身和w必须是兄弟关系小部件和w都继承于一个父类。 例如我想在当前弹窗下放置一个窗口当前窗口继承与QDialog那么要放置的窗口也必须继承与QDialog。
如何获取父类的窗口
QWidget* mainWindow this-parentWidget()比如
自定义数据类型Q_DECLARE_METATYPE()注册
QFontMetrics函数计算给定字体的字符和字符串的大小。 QFont font(times, 24);QFontMetrics fm(font);int pixelsWide fm.width(Whats the width of this text?);int pixelsHigh fm.height();QString elidedText(const QString text, Qt::TextElideMode mode, int width, int flags 0) const;(Elide省略的意思) 如果字符串文本的宽度大于width则返回字符串的省略版本(即包含…的字符串)。否则返回原始字符串。
enum TextElideMode {ElideLeft, //省略号在左边ElideRight, //省略号在右边ElideMiddle, //省略号在中间ElideNone //无省略号};宏
Q_ASSERT
Q_ASSERT是一个宏接受布尔值当其中的布尔值为真时便什么也不做当其中的布尔值为假时便断下。
Q_ASSERT(index.isValid());编译常见错误
error: static assertion failed: The slot requires more arguments than the signal provides. [ #define Q_STATIC_ASSERT_X(Condition, Message) static_assert(bool(Condition), Message)]
原因一般是信号与槽的参数不一致导致的
error: No rule to make target ‘xxx.png’, needed by ‘debug/qrc_resource.cpp’. Stop.
原因在项目当中删除resourse下的图片导致的 解决重新执行qmake即可
error: [debug/qrc_resource.cpp] Error 1 原因项目中添加此图片但是文件中并不存在此图片或已删除此时找不到所以报错 怎么找这个不存在的图片 方法一个一个去点击图片当点击到不存在的图片时会显示以下错误
解决删除项目中此图片重新添加
error: field has incomplete type
原因只是前向声明并没有包含include文件 解决包含include文件
error: jump to case label [-fpermissive] case xxx: ^
原因case语句之后如果有多行定义代码特别是变量定义最好使用{}来给予约束作用域负责计算机无法识别作用域。 解决case语句之后的代码加上{}
//错误示范
switch (a)
{case 1:int a 0;//stuffbreak;case 2://stuffbreak;
}//正确示范
switch (a)
{case 1:{int a 0;//stuff}break;case 2://stuffbreak;
}error: passing ‘const ProjectTreeViewDelegate’ as ‘this’ argument discards qualifiers [-fpermissive] drawTreeViewItem(painter, drawRect, modelData);^
原因当某一个函数是const函数时另一个函数会调用这个函数的参数则另一个函数也应设为const 解决另一个函数也应为const函数
错误示范
void paint(QPainter* painter, const QStyleOptionViewItem option, const QModelIndex index) const override;
void drawTreeViewItem(QPainter* painter, QRect drawRect, ProjectTreeModelData modelData); //错误正确示范
//drawTreeViewItem参数里面会调用paint的参数paint为const函数则drawTreeViewItem也应为const函数
void paint(QPainter* painter, const QStyleOptionViewItem option, const QModelIndex index) const override;
void drawTreeViewItem(QPainter* painter, QRect drawRect, ProjectTreeModelData modelData) const;另外一种情况 在const函数里面不能改变成员变量的值或赋值
error: default argument given for parameter x of
原因默认参数既可以在函数声明中也可以在函数定义中声明缺省参数但不能既在函数声明中又在函数定义中同时声明缺省参数。 解决将定义或声明中的任一个缺省参数删除即可。
错误示范
//.h文件
void func(int a, int b 0);
//.cpp文件
void func(int a, int b 0); //错误正确示范
//.h文件
void func(int a, int b 0);
//.cpp文件
void func(int a, int b);error: static assertion failed: Signal and slot arguments are not compatible.
原因信号的参数与槽函数参数不对应 解决信号的参数与槽函数参数改为一致
错误示范
//信号
sigData(int a);
//槽函数
slotGetData(float a); //错误参数不一致正确示范
//信号
sigData(int a);
//槽函数
slotGetData(int a);error: invalid application of ‘sizeof’ to incomplete type ‘XXX’‘VariableData’: sizeOf sizeof(T)
原因前置声明一个类只是声明并不知道类的大小 解决使用include包含头文件
错误示范
class B; //只是声明
class A {...QListB m_ list; //无法知道类B的大小
};正确示范
#include B.hclass A {...QListB m_ list;
};关于内联inline的 error: invalid use of incomplete type ‘xxx’
原因inline在头文件声明在源文件定义时若其他文件调用inline函数时会出现此种错误。因为该函数对其他编译单元不可见也就是其他cpp文件不能链接该函数库。 解决inline函数的声明和定义都写在头文件中
如果将函数的实现放在头文件中那么每一个包含该头文件的cpp文件都将得到一份关于该函数的定义那么链接器会报函数重定义错误。如果将函数的实现放在头文件并且标记为 inline 那么每一个包含该头文件的cpp文件都将得到一份关于该函数的定义并且链接器不会报错。如果将函数的实现放在cpp文件中并且没有标记为inline,那么该函数可以被连接到其他编译单元中。如果将函数的实现放在cpp文件中并且标记为inline, 那么该函数对其他编译单元不可见类似static的效果也就是其他cpp文件不能链接该函数库这就是标题中出现的 … undefined reference to …
槽函数的lambda错误 error: passing ‘const VarBasicData’ as ‘this’ argument discards qualifiers [-fpermissive][](const VarBasicData varinfo) { varData.basic varinfo; });
原因参数是const的赋值的时候会出错 解决 添加mutable关键字
错误示范
connect(SignalsMedium::getInstance(), SignalsMedium::sigBasicVarInfo,[](const VarBasicData varinfo) { varData.basic varinfo; });正确示范
connect(SignalsMedium::getInstance(), SignalsMedium::sigBasicVarInfo,[](const VarBasicData varinfo) mutable { varData.basic varinfo; });update()的作用
用于更新UI界面的它会触发重绘事件并调用paintEvent函数。 在QWidget或其子类中可以通过调用update函数来触发重绘事件从而更新UI界面。
QColor
打印颜色的名称
QString QColor::name() constqDebug() color.name();基本颜色
QString arrayColor[5][8] {{#000000, #A52A2A, #004040, #005500, #00005E, #00008B, #4B0082, #696969},{#8B0000, #FF6820, #8B8B00, #009300, #388E8E, #0000FF, #7B7BC0, #808080},{#FF0000, #FFAD5B, #32CD32, #3CB371, #7FFFD4, #7D9EC0, #800080, #A9A9A9},{#FFC0CB, #FFD700, #FFFF00, #00FF00, #40E0D0, #C0FFFF, #480048, #C0C0C0},{#FFE4E1, #D2B48C, #FFFFE0, #98FB98, #AFEEEE, #68838B, #E6E6FA, #FFFFFF}};QString arrayToolTip[5][8] {{Black, Brown, Dark Olive Green, Dark Green, Dark Teal, Dark Blue, Indigo, Dark Gray},{Dark Red, Orange, Dark Yellow, Green, Teal, Blue, Blue Gray, Gray},{Red, Light Orange, Lime, Sea Green, Aqua, Light Blue, Violet, Dim Gray},{Pink, Gold, Yellow, Bright Green, Turquoise, SkyBlue, Dark Magenta, Light Gray},{Light Pink, Tan, Light Yellow, Pale Green, Pale Turquoise, Pale Blue, Lavender, White}};event: 设置鼠标进入和离开时的框架样式
bool BasicColorItem::event(QEvent* event) {/*鼠标进入时的框架样式*/if (QEvent::Enter event-type()) {setLineWidth(0);setMidLineWidth(0);setFrameShape(QFrame::WinPanel);setFrameShadow(QFrame::Raised);}/*鼠标离开时的框架样式*/if (QEvent::Leave event-type()) {initItemFram();}return QLabel::event(event);
}.pri中的INCLUDEPATH的作用
若有INCLUDEPATH $$PWD/treeview/ 则在其他层级的文件中直接#include “abc.h”
若没有INCLUDEPATH $$PWD/treeview/ 则在其他层级的文件中需要一级一级查找并include#include “xxx/yyy/zzz/abc.h”
只设置右上角的关闭按钮
setWindowFlags(Qt::Dialog | Qt::WindowCloseButtonHint);setWindowModality(Qt::WindowModal); //模态窗口在break之前可以直接return吗switch中return后是否需要break
在switch中使用return不仅会跳出switch还会直接结束循环。 已知执行到break就会跳出switch不再执行后面的语句return也有同样的效果。
在idea中无论是在return后面写break还是在break后写return都会直接报错无法到达这条语句
多层for循环break只会跳出一层循环
QTreeView
set属性设置
setHeaderHidden(true); //隐藏标题
setExpandsOnDoubleClick(false); //是否双击展开项
setRootIsDecorated(false); //是否显示展开和折叠顶级项的控件(v和)
setEditTriggers(QAbstractItemView::NoEditTriggers); //不可编辑
setIndentation(0); //所有项的缩进为0
setAcceptDrops(true); //接受拖放事件
setAnimated(true); //子项展开的动画setExpanded不展开的问题
问题当前item下没有子节点时则setExpanded无效。必须先appendRow()再setExpanded() setExpanded必须从顶节点开始向下设置若从最下面的节点向上设置则无效。
setExpanded从内向外设置无效先设置从子孙节点再设置父节点例子
QStandardItem* currentItem new QStandardItem;
m_model-appendRow(currentItem);
for(int i 0; i 3; i){QStandardItem* childItem new QStandardItem;for(int i 0; i 5; i){QStandardItem* grandsonItem new QStandardItem;childItem-appendRow(grandsonItem);}//此时想的是给childItem添加完子节点后再去展开它但是当前节点的父节点都不知道展开了没有在这里展开子节点是豪无意义的//所以这里的childItem展开是无效的。在这之前必须先设置父节点的setExpandedsetExpanded(childItem -index(), true); currentItem-appendRow(childItem );
}
setExpanded(currentItem-index(), true); //currentItem展开以上代码会导致childItem不会展开
改正setExpanded必须从外向内设置从父到子再到孙进行设置setExpanded
//每次appendRow之后就setExpanded
QStandardItem* currentItem new QStandardItem;
m_model-appendRow(currentItem);
setExpanded(currentItem-index(), true); //currentItem展开
for(int i 0; i 3; i){QStandardItem* childItem new QStandardItem;currentItem-appendRow(childItem ); setExpanded(childItem -index(), true); for(int i 0; i 5; i){QStandardItem* grandsonItem new QStandardItem;childItem-appendRow(grandsonItem);}
}迭代器怎么赋值使用*blockIter
for (QListBlockData::iterator blockIter osciModelData.oscilloscope.blockDList.begin();blockIter ! osciModelData.oscilloscope.blockDList.end(); blockIter) {if (blockModelData.block.uid blockIter-uid) { //找到是哪个Block*blockIter blockModelData.block;}
}枚举的定义
不同枚举类型的枚举元素不能同名
findChild的使用
返回parentWidget中一个名为“button1”的QPushButton孩子即使按钮不是父亲的直接孩子
QPushButton *button parentWidget-findChildQPushButton *(button1);返回parentWidget中的一个QListWidget孩子
QListWidget *list parentWidget-findChildQListWidget *();返回parentWidget它的直接父亲中一个名为“button1”的QPushButton孩子
QPushButton *button parentWidget-findChildQPushButton *(button1, Qt::FindDirectChildrenOnly);返回parentWidget它的直接父亲中的一个QListWidget孩子
QListWidget *list parentWidget-findChildQListWidget *(QString(), Qt::FindDirectChildrenOnly);connect
connect写法
connect的lambda表达式
connect(pushButton, QPushButton::clicked, [](){...});
// []代表把外部所有局部变量、类中所有成员以值的传递方式如果当前connect处于某个函数中则表示当前函数下的所有变量、类中所有成员以值的传递方式
// [this]代表把类中所有成员以值的传递方式
// []代表把外部所有局部变量、类中所有成员以引用的传递方式如果当前connect处于某个函数中则表示当前函数下的所有变量、类中所有成员以引用的传递方式
// ()传递过来的参数connect(m_var, QPushButton::sigSetVar, [](const VarData data) mutable {...});
//如果参数为const类型并且后面使用到该参数比如赋值之类的需要写mutable去掉const属性lambda中的值捕获[]与引用捕获[]
以值捕获 [] ProjectTreeModelData varModelData varStandardItem-data(Qt::UserRole 1).valueProjectTreeModelData();connect(colorWidget, ColorSelectedDialog::sigBasicColor, [](const QColor color) mutable {//此时获得是varModelData的副本varModelData.variable.variableData.lineColor color.name(); //若color是蓝色colorWidget-close();});//因为上面的赋值是赋给varModelData的副本这里的setData中varModelData中lineColor还是原来的颜色varStandardItem-setData(QVariant::fromValue(varModelData), Qt::UserRole 1);//此时获得的varModelData中lineColor还是原来的颜色并没有改变为蓝色varModelData varStandardItem-data(Qt::UserRole 1).valueProjectTreeModelData(); 以引用捕获 [] ProjectTreeModelData varModelData varStandardItem-data(Qt::UserRole 1).valueProjectTreeModelData();connect(colorWidget, ColorSelectedDialog::sigBasicColor, [](const QColor color) mutable {//此时获得是varModelData本身而非副本varModelData.variable.variableData.lineColor color.name(); //若color是蓝色colorWidget-close();});//因为上面的赋值是赋给varModelData结构本身这里的setData中varModelData中lineColor已成为蓝色varStandardItem-setData(QVariant::fromValue(varModelData), Qt::UserRole 1);//此时获得的varModelData中lineColor变为蓝色varModelData varStandardItem-data(Qt::UserRole 1).valueProjectTreeModelData(); 发信号之前一定还要先建立连接connect
比如再给另一个界面发送数据时一定要先在那个界面当中connect建立连接否则信号执行那边接收不到数据。
再比如一定要在一个界面exec()之前写connect因为exec()会阻塞下面的代码
一般情况写在构造函数里面在初始化的时候开始监听。具体情况具体处理。
connect中嵌套connect注意重复连接
connect(addVarAct, QAction::triggered, []() {connect(SignalsMedium::getInstance(), SignalsMedium::sigBasicVarInfo,[](const VarBasicData varinfo) mutable { addVariable(blockStandardItem, varinfo); });问题connect中套connect造成里面的connect重复连接。 解决使用disconnect断开连接
connect(addVarAct, QAction::triggered, []() {connect(SignalsMedium::getInstance(), SignalsMedium::sigBasicVarInfo,[](const VarBasicData varinfo) mutable { addVariable(blockStandardItem, varinfo); });.../** 必须断开连接否则会每点一次就会多连接一次造成重复连接 **/disconnect(SignalsMedium::getInstance(), SignalsMedium::sigBasicVarInfo, 0, 0);connect的参数
一个信号可以连接到多个槽和信号。如果一个信号连接到多个槽当信号发出时这些槽会按照连接的顺序被激活。 enum Qt::ConnectionType
ConstantValueDescriptionQt::AutoConnection0默认值如果接收器位于发出信号的线程中则使用Qt::DirectConnection。否则使用Qt::QueuedConnection。在发出信号时确定连接类型。Qt::DirectConnection1当发出信号时立即调用该槽。槽在同一线程中执行。Qt::QueuedConnection2当控制返回到接收者线程的事件循环时调用该槽。槽在接收者的线程中执行。Qt::BlockingQueuedConnection3与Qt::QueuedConnection相同除了信号线程阻塞直到插槽返回。如果发送方和接收方处于同一线程中则不能使用此连接否则应用程序将死锁。Qt::UniqueConnection0x80这是一个标志可以使用位或与上述任何一种连接类型组合使用。如果当前信号与槽连接过了就不再连接了防止重复连接。
怎样避免connect重复连接
特别是connect里面嵌套connect这种情况特别容易造成内部的connect重复连接 解决 1disconnect某些情况下如果内部每一次的connect处理不同的事最好使用disconnect 2在构造里面写connect不是所有的connect都可以写在构造里面如果有一个界面在构造中没有被new出来那与该界面绑定的connect就无效 3blockSignals(阻塞某一个控件的所有信号发送) 4Qt::UniqueConnection某些情况下如果内部每一次的connect处理相同的事则使用Qt::UniqueConnection
信号槽连接 函数重载、参数不一致问题
QT5写法导致编译错误
connect(m_thread, QThread::started, m_timer, QTimer::start); //线程开始定时器开始原因start()为重载函数由于QT5这种方式没有标明参数编译器就无法确定连接的是哪一个函数从而报错 只能使用QT4的写法
connect(m_thread, SIGNAL(started()), m_timer, SLOT(start())); //线程开始定时器开始Dialog鼠标在窗口外区域点击时关闭该窗口
适用于模态的dialog
设置窗口属性为 Qt::Popup可自动实现窗口外点击关闭窗口
setWindowFlags(Qt::Popup);以下两种方法不适用于模态的dialog只适用于非模态的dialog和widget
重写鼠标点击事件 (mousePressEvent())若鼠标位置不在该窗口区域内关闭窗口重写焦点失去事件 (focusOutEvent())若窗口失去焦点关闭窗口
QModelIndex
返回当前Index的第row行第column列的兄弟Index
QModelIndex::sibling(int row, int column)兄弟之间的index都可以互相得到只需要知道兄弟的行和列。
QModelIndex index0 index1.sibling(index.row(), 0);
QModelIndex index3 index1.sibling(index.row(), 3;cpp
QModelIndex index0 index1.sibling(0, index.column());
QModelIndex index3 index1.sibling(3, index.column());删除树的子节点
错误示范
// 每移除一个子节点其m_projectNameItem-rowCount()都会少1
//而移除的是m_projectNameItem-child(i)导致某些子节点没有删除
if (m_projectNameItem-hasChildren()) {for (int i 0; i m_projectNameItem-rowCount(); i) {removeStandardItem(m_projectNameItem-child(i), m_projectNameItem);}
}
m_model-removeRow(m_projectNameItem-row());正确示例
//先确定有多少个子节点
//每次都删第一个才能保证删完
if (m_projectNameItem-hasChildren()) {int count m_projectNameItem-rowCount();for (int i 0; i count; i) {removeStandardItem(m_projectNameItem-child(0), m_projectNameItem);}
}
m_model-removeRow(m_projectNameItem-row());递归删除树的子节点
removeStandardItem(QStandardItem* standardItem, QStandardItem* parentStandardItem) {int count standardItem-rowCount();if (0 count) {parentStandardItem-removeRow(standardItem-row());return;}for (int i 0; i count; i) {QStandardItem* childStandardItem standardItem-child(0);removeStandardItem(childStandardItem, standardItem);}parentStandardItem-removeRow(standardItem-row());
}QLineEdit
setText会触发QLineEdit的textChanged信号
设置不可编辑状态
setReadOnly(true); //只读当前坐标与全局坐标的转换
QRect toolRect geometry();
QPoint point(geometry().x 100, geometry().y());
QPoint globalPoint mapToGlobal(point);判断当前焦点是否在某控件上
hasFocus();Qt获得和失去焦点事件
重写控件的focusInEvent()和focusOutEvent()函数
void focusInEvent(QFocusEvent *event) override;
void focusOutEvent(QFocusEvent *event) override;关于List的比较
//错误示范
if (RTTVarList.at(i).basic varModelData.variable.variableData.basic) {...}//正确示范
//list的at()是const类型的放在的右边
if (varModelData.variable.variableData.basic RTTVarList.at(i).basic) {...}drag拖动如何显示拖动禁用的标志
在dragMoveEvent(QDragMoveEvent* event)里实现在移动到某些位置就会出现禁用的标志
//当鼠标移动到rect里面时接受该事件否则忽略该事件就会出现禁用标志
void dragMoveEvent(QDragMoveEvent* event){QRect rect(0,0,100,30);if(ret.contains(event.pos())){event-accept();}else{event-ignore(); }
}QFileDialog
enum QFileDialog::AcceptMode
文件对话框打开的样式
AcceptOpen打开文件 AcceptSave保存文件
enum QFileDialog::DialogLabel
对话框中的标签可使用 setLabelText() 设置标签上的文本。 LookIn FileName FileType Accept Reject
setFocus不生效的问题
不能在你的部件还不可见的时候去setFocus这样不行。 解决这个问题的办法就是把setFocus()的操作放到我们这个部件的**showEvent()**里面去做。 而我们一般可能喜欢放到构造函数最后去setFocus这样往往是没有效果的问题就在这。
void DisplayWidget::showEvent(QShowEvent* event) {Q_UNUSED(event);m_osciNameLine-setFocus();
}