一、按钮类控件
1.QPushBUtton
QPushButton表示一个按钮控件,它继承自QAbstractButton,这个类是一个抽象类,是其他按钮的父类。其继承关系如图1所示。1.1 text属性
text属性对应于QPushButton控件上的文本信息,可以使用setText()设置text属性。
1.2 icon/iconSize属性
icon属性对应于QPushButton控件上的图标信息,可以使用setIcon()设置icon属性。对应的图标可以使用QT的资源文件的方式形成qrc文件,在通过setIcon()设置。关于qrc文件的相关操作已经在常用控件一说过了,此处不再赘述。
iconSize属性对应于QPushButton控件上的图标信息,可以使用setIconSize()设置iconSize属性。
1.3 shortCut属性
1)shortCurt属性对应QPushButton控件的快捷键信息,可以使用setShortCurt()设置shortCurt属性。当使用组合快捷键时需要使用QkeySequence()去构造一个对象,在使用setShortCurt()设置shortCurt属性。QKeySequence::QKeySequence(int k1, int k2 = 0, int k3 = 0, int k4 = 0),参数K1-K4可以使用Qt::Key和Qt::Modifier中枚举出的键,eg:Qt::CTRL、Qt::Key_Shift、Qt::SHIFT。Qt::Modifier中是一些键名的简称只有5个键,且全为大写字母,eg:CTRL、SHIFE、ALT、META、UNICODE_ACCEL。Qt::Key中是一些键名的全称,都是以Key_为前缀加键名,eg:Key_Shift,可以发现shift在两个类里面都有,而ctrl只有Qt::Modifier中有。注意,这些键使用时需要加Qt命名空间。
2)此外还可以使用QKeySequence::QKeySequence(const QString &key, QKeySequence::SequenceFormat format = NativeText)去构造对象设置shortCurt属性。此时只需要传入一个QString类型的字符串即可,eg:“ctrl+c”。使用这种方式构造对象后,如果拼写有错误不会报错,建议使用前一种方法构造对象设置shortCurt属性
1.4 autoRepeat属性
autoRepeat属性对应于QPushButton控件是否会重复触发。当鼠标左键按住不放时,如果设为 true,则会持续产生鼠标点击事件(相当于游戏手柄上的 “连发” 效果)。如果设为false, 则必须释放鼠标, 再次按下鼠标时才能产生点击事件,可通过setAutoRepeat()来设置。注意:使用快捷键时默认支持连续触发,使用鼠标点击时连续触发需要设置。
1.5 autoRepeatDelay属性
autoRepeatDelay属性对应于QPushButton控件重复触发的延时时间。即按住按钮多久之后, 开始重复触发。可通过setAutoRepeatDelay()设置,单位为ms。注意,设置之后对快捷键触发没有影响,只对鼠标触发生效,即设置之后快捷键的连续触发还是立即触发,没有延时。
1.6 autoRepeatInterval属性
autoRepeatInterval属性对应于QPushButton控件重复触发的周期,可通过setAutoRepeatInterval()设置,单位为ms。注意,设置之后对快捷键触发没有影响,只对鼠标触发生效,即设置之后快捷键的连续触发周期不变。
#include "mywidget.h"
#include "ui_mywidget.h"
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MyWidget)
{
ui->setupUi(this);
QKeySequence();
ui->label->setPixmap(QPixmap(":/picture/picture1"));//设置label的图标
ui->label->setScaledContents(true);//设置label的图标自动填充到label的大小
//设置快捷键
ui->PBt_Up->setShortcut(QKeySequence(Qt::Key_Up));
ui->PBt_Down->setShortcut(QKeySequence(Qt::Key_Down));
ui->PBt_Left->setShortcut(QKeySequence(Qt::Key_Left));
ui->PBt_Right->setShortcut(QKeySequence(Qt::Key_Right));
ui->PBt_Up->setIcon(QIcon(":/key/up")); //设置按钮图标
ui->PBt_Up->setIconSize(QSize(50,50)); //设置按钮图标大小
ui->PBt_Up->setAutoRepeat(true);//设置鼠标点击按钮是否连续触发
ui->PBt_Up->setAutoRepeatDelay(3000); //设置鼠标点击按钮连续触发延时时间,ms
ui->PBt_Up->setAutoRepeatInterval(1000);//设置鼠标点击按钮连续触发的时间周期,ms
ui->PBt_Down->setIcon(QIcon(":/key/down"));
ui->PBt_Down->setIconSize(QSize(40,40));
ui->PBt_Down->setAutoRepeat(true);
ui->PBt_Left->setIcon(QIcon(":/key/left"));
ui->PBt_Left->setIconSize(QSize(50,50));
ui->PBt_Left->setAutoRepeat(true);
ui->PBt_Right->setIcon(QIcon(":/key/right"));
ui->PBt_Right->setIconSize(QSize(50,50));
ui->PBt_Right->setAutoRepeat(true);
}
2.QRadioButton
QRadioButton是单选按钮,可以让我们在多个选项中选择一个。2.1 checkable/checked属性
checkable属性对应于QRadioButton控件是否能够被选中。setCheckable(false)之后,QRadioButton控件将无法被选中。checked属性对应于QRadioButton控件是否已经被选中,checkable是checked的前提条件。可以通过RBt->setChecked(true)设置对应的QRadioButton控件为选中状态作为默认选项。注意,setCheckable(false)之后虽然无法选中该QRadioButton控件,但是与该QRadioButton控件相连接的槽函数如果达到触发条件依然会触发,因此在禁用QRadioButton控件时最好使用RBt->setEnable(false)来设置。
上面两段代码中RBt_forbid所连接的槽函数不同,图3中RBt_forbid的槽函数是clicked触发,即点击触发。虽然setCheckable(false)设置无法选中该选项,但是还是可以点击该控件,达到了槽函数的触发条件,故执行了槽函数。图4中RBt_forbid的槽函数是toggleed触发,即状态翻转触发(选中->未选中or未选中->选中)。因为RBt_forbid无法选中,一直处于未选中状态,无法完成状态翻转,故不会触发槽函数。因此可以确定setCheckable(false)之后的QRadioButton控件依然会触发槽函数。我们在设计程序时应该区分开各触发信号的区别,选择合适的信号触发槽函数。
2.2 autoExclusive属性
autoExclusive属性对应于QRadioButton控件是否排他,即选中一个按钮之后是否会取消其他按钮的选中,对于QRadioButton来说默认就是排他的。可以通过setAutoExclusive()来设置是否排他。我们可以通过构造一个QButtonGroup对象,使用addButton()将多个按钮放到这个组对象中形成一组按钮,这样可以使组内排他,组与组之间的按钮不排他。
3.QCheckBox
QCheckBox表示复选按钮,可以允许选中多个。和QCheckBox最相关的属性也是checkable和checked ,都是继承自QAbstractButton,在QRadioButton中已经讲过,此处不在赘述。tristate用来实现 "三态复选框",此处不做讨论。二、显示类控件
1.QLable
1.1 text文本相关属性
1)text属性:该属性和其他控件的text属性一样,对应于该控件上的文本。该属性在其他控件上已经使用多次,此处不在赘述。
2)textFormat属性:该属性对应于QLabel中文本的格式。共支持4种文本格式,Qt::PlainText(纯文本格式)、Qt::RichText(富文本格式,支持html标签)、Qt::MarkdownText(markdown格式)、Qt::AutoText(根据文本内容自动决定文本格式)。
3)alignment属性:该属性对应于QLabel中文本对齐方式,可以设置水平和垂直方向如何对齐。默认对齐方式为水平靠左垂直居中对齐。对齐方式在AlignmentFlag中进行了枚举,enum AlignmentFlag的内容如下:
enum AlignmentFlag {
AlignLeft = 0x0001,
AlignLeading = AlignLeft,
AlignRight = 0x0002,
AlignTrailing = AlignRight,
AlignHCenter = 0x0004,
AlignJustify = 0x0008,
AlignAbsolute = 0x0010,
AlignHorizontal_Mask = AlignLeft | AlignRight | AlignHCenter | AlignJustify | AlignAbsolute,
AlignTop = 0x0020,
AlignBottom = 0x0040,
AlignVCenter = 0x0080,
AlignBaseline = 0x0100,
// Note that 0x100 will clash with Qt::TextSingleLine = 0x100 due to what the comment above
// this enum declaration states. However, since Qt::AlignBaseline is only used by layouts,
// it doesn't make sense to pass Qt::AlignBaseline to QPainter::drawText(), so there
// shouldn't really be any ambiguity between the two overlapping enum values.
AlignVertical_Mask = AlignTop | AlignBottom | AlignVCenter | AlignBaseline,
AlignCenter = AlignVCenter | AlignHCenter
};
可见对齐方式是位图结构,不同的对齐方式可以是用按位或的方式形成组合的对齐方式,在QT的这个枚举内部也进行了说明。在使用时需要加Qt的命名空间
4)wordWrap属性:该属性对应于QLabel中文本是否自动换行。
5)indent属性:设置文本缩进,水平和垂直方向都生效,单位为像素。缩进只缩进对齐的位置,如果是水平靠左、垂直顶部对齐则左缩进指定像素,顶部缩进指定像素。
6)margin属性:内部文本和边框之间的边距,不同于于indent, 是上下左右四个方向都同时有效。而indent最多只是两个方向有效(具体哪两个方向有效取决于alignment)
1.2 图片相关属性
1)pixmap属性:QLabel内部包含的图片。
2)scaledContents属性:设为 true 表示内容自动拉伸填充QLabel设为false则不会自动拉伸
3)framShape属性:QLabel边框的样式。
#include "mywidget.h"
#include "ui_mywidget.h"
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::MyWidget)
{
ui->setupUi(this);
ui->label->setTextFormat(Qt::PlainText);
ui->label->setText("<b>纯文本格式</b>,这是一段水平靠右,垂直底部对齐的文本");
ui->label->setWordWrap(true); //设置自动换行
ui->label->setMargin(20); //文本距离边框20像素
ui->label_2->setTextFormat(Qt::RichText);
ui->label_2->setAlignment(Qt::AlignLeft | Qt::AlignTop);//设置对齐方式
ui->label_2->setWordWrap(true); //设置自动换行
ui->label_2->setIndent(20); //缩进20像素
ui->label_2->setText("<b>富文本格式,水平靠左,垂直顶部对齐,这是一段可以自动换行且很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的文本</b>");
ui->label_3->setTextFormat(Qt::MarkdownText);
ui->label_3->setIndent(20); //缩进20像素
ui->label_3->setText("<font color=Red>Markdown格式,这是一段没有自动换行且很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长很长的文本</font>");
ui->label_4->setPixmap(QPixmap(":/picture/res.jpg"));
//ui->label_4->setScaledContents(true);
}
在一个窗口创建一个和窗口大小一样的Label,然后设置自动填充填满整个窗口,当我们使用鼠标拖动窗口时,发现让图片不会随窗口大小而改变。我们可以通过什么方式来解决这个问题?事实上,用户在拖动修改窗口大小时,会触发resize事件(resizeEvent()),resize这样的事件时连续变化的,拖动窗口改变窗口尺寸大小这个过程会触发一系列的resizeEvent,此时我们就可以借助resizeEvent来完成上述功能。让widget窗口类,重写父类(QWidget)的resizeEvent虚函数,在拖动窗口的过程中,这个函数会被反复调用执行。每触发一个resizeEvent事件都会调用一次对应的虚函数virtual void resizeEvent(QResizeEvent *event),参数event中是事件产生这一时刻的窗口尺寸。我们可以在虚函数中将Label的大小设置成参数event中窗口的大小。
1.3 其他相关属性
1)openExternalLinks属性:是否允许打开一个外部的链接(当QLabel文本内容包含url的时候涉及到),这种方式下打开外部链接,必须在QLabel的文本内容为富文本,且格式严格按照html标签的方式才可以。
2)buddy属性:给 QLabel 关联一个 “伙伴” ,这样点击QLabel时就能激活对应的伙伴,例如伙伴如果是一个QCheckBox,那么该QCheckBox就会被选中。在QLabel的文本中可以通过&+按键的方式设置快捷键,这种快捷键使用是必须使用Alt+快捷键的方式才会触发,如果绑定了伙伴关系就可以通过快捷键选中对应的单选/复选按钮。
2.QLcdNumber
2.1 intValue/value属性
1)intValue:QLCDNumber显示的数字值为int类型。
2)value:QLCDNumber 显示的数字值为double类型,它和intValue是联动的,eg:如果value设为1.5,intValue值就是2。注意:设置value和intValue的方法名字为display,而不是setValue或者setIntValue
2.2 digitCount/mode属性
1)digitCount:显示几位数字。
2)mode:数字显示形式。一共支持4中数字的显示形式。QLCDNumber::Dec(十进制模式,显示常规的十进制数字),QLCDNumber::Hex(十六进制模式,以十六进制格式显示数字),QLCDNumber::Bin(二进制模式,以二进制格式显示数字),QLCDNumber::Oct(八进制模式,以八进制格式显示数字)。注意,只有十进制的时候才能显示小数点后的内容。
2.3 segmentStyle属性
segmentStyle属性用于设置设置显示风格。一共支持3种显示风格。QLCDNumber::Flat(平面的显示风格,数字呈现在一个平坦的表面上),QLCDNumber::Outline(轮廓显示风格,数字具有清晰的轮廓和阴影效果),QLCDNumber::Filled(填充显示风格,数字被填充颜色并与背景区分开)。
2.4 smallDecimalPoint属性
smallDecimalPoint属性用于设置比较小的小数点。此处利用QLcdNumber实现一个10s倒计时的实例来熟悉相关属性。
在QT中有封装QTimer定时器。通过start方法传入参数(触发周期,单位为ms)启动定时器之后,就会每隔一定周期,触发一次QTimer::timeout信号。使用connect把QTimer::timeout信号和自定义槽函数连接起来,意味着每次触发 QTimer::timeout都会执行我们的自定义槽函数,我们可以在自定义槽函数里面刷新QLcdNumber的显示,实现倒计时功能。
2) 使用标准库中的sleep_for()循环休眠1s,每次休眠之后修改lcdNumber的显示数值完成倒计时功能。
#include "mywidget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyWidget w;
w.show();
return a.exec();
}
运行之后发现,窗口并没有立即显示,但程序输出窗口可以看到剩余时间一直在变,看main函数得出结论。我们在构造函数中进入循环,当循环结束之后才会调用show()进行显示,所以我们只看到倒计时结束显示的那个页面。那么可以通过创建一个线程的方式来解决这个问题吗?让主线程执行循环显示窗口功能,我们创建的线程修改lcdNumber的显示数值。其结果如下图14所示。
通过程序输出窗口可以发现,运行之后程序异常结束。
在QT中,界面是有一个专门的线程去负责维护更新的,也就是main函数所在的主线程。对于GUI来说内部包含了很多的隐藏状态,QT为了保证修改界面过程中线程安全,禁止了其他线程直接修改界面。也就是说界面是一块临界资源,如果可以被多个线程修改会造成不确定性结果,为了安全必须要进行加锁等措施进行防护。但是不确定性因素太多,加锁之后可能会出现其他问题,所以QT直接禁止了其他线程访问这块资源,这样就不存在临界资源了,保证了线程安全。对于QT来说,其槽函数在默认情况下都是由主线程调用的,所以我们在槽函数中修改界面是没有问题的。
3.ProgressBar
QProgressBar进度条的相关属性如下表,此处不在做详细描述,后面通过示例说明进度条的使用。属性 | 说明 |
---|---|
minimum | 进度条最小值 |
maximum | 进度条最大值 |
value | 进度条当前值 |
alignment | 文本在进度条中的对齐方式 Qt::AlignLeft:左对齐 Qt::AlignRight:右对齐 Qt::AlignCenter:居中对齐 Qt::AlignJustify:两端对齐 |
textVisible | 进度条的数字是否可见 |
orientation | 进度条的方向是水平还是垂直 |
invertAppearance | 是否是朝反方向增长进度 |
textDirection | 文本的朝向 |
format | 展示的数字格式 %p:表示进度的百分比(0-100) %v:表示进度的数值(0-100) %m:表示剩余时间(以毫秒为单位) %t:表示总时间(以毫秒为单位) |
其中进度条的颜色我们可以使用样式表来编辑,需要遵循qss的语法。也可以编辑代码实现,通过定义一个符合qss语法的QString字符串,然后使用setStyleSheet将相关样式设置进QProgressBar。参考博客:
Qt实战案例(23)——利用QProgressBar实现彩色进度条
同理,其他控件也可以通过这种方式来设置控件的样式来美化界面。qss语法参考博客:
Qt界面美化QSS——(一)使用方式、语法(选择器、伪状态)
4.QCalendarWidget
QCalendarWidget日历的相关属性如下表,此处不在做详细描述,后面通过示例说明日历的使用。属性 | 说明 |
---|---|
selectDate | 当前选中的日期 |
minimumDate | 最小日期 |
maximumDate | 最大日期 |
firstDayOfWeek | 每周的第一天(也就是日历的第一列) 是周几 |
gridVisible | 是否显示表格的边框 |
selectionMode | 是否允许选择日期 |
navigationBarVisible | 日历上方标题是否显示 |
horizontalHeaderFormat | 日历上方标题显示的日期格式 |
verticalHeaderFormat | 日历第一列显示的内容格式 |
dateEditEnabled | 是否允许日期被编辑 |
重要信号:
信号 | 说明 |
---|---|
selectionChanged(const QDate&) | 当选中的日期发生改变时发出 |
activated(const QDate&) | 当双击一个有效的日期或者按下回车键时发出,形参是一个QDate类型,保存了选中的日期 |
currentPageChanged(int,int) | 当年份月份改变时发出,形参表示改变后的新年份和月份代 |