在 Qt 中,我们将窗口和控件统称为部件(Widget)
窗口是指程序的整体界面,可以包含标题栏、菜单栏、工具栏、关闭按钮、最小化按钮、最大化按钮等。
控件是指按钮、复选框、文本框、表格、进度条等这些组成程序的基本元素。一个程序可以有多个窗口,一个窗口也可以有多个控件。
QWidget 是所有用户界面元素的基类,窗口和控件都是直接或间接继承自 QWidget,QMainWindow、QWidget、QDialog 三个类就是用来创建窗口的,可以直接使用也可以继承后再使用。
QWidget类是所有用户界面对象的基类。 窗口部件是用户界面的一个基本单元:它从窗口系统接收鼠标、键盘和其它事件,并且在屏幕上绘制自己。每一个窗口部件都是矩形的,并且它们按Z轴顺序排列。一个窗口部件可以被它的父窗口部件或者它前面的窗口部件盖住一部分。
setWindowTitle:设置标题
setWindowIcon:设置图标
setFixedSize:设置固定窗口大小
resize:设置窗口大小
setLayout:设置布局
show:显示
setStyleSheet:设置窗口样式
update:刷新窗口
void setAttribute(Qt::WidgetAttribute, bool on = true);
WA_DeleteOnClose = 55, //窗口关闭删除自己,释放内存
WA_AcceptDrops = 78, //允许窗口接收拖放来的组件
void setWindowFlags(Qt::WindowFlags type);
WindowStaysOnTopHint = 0x00040000, //窗口现在在最上层
void setWindowState(Qt::WindowStates state);
WindowFullScreen = 0x00000004,//满屏
void setWindowOpacity(qreal level); //1-0之间 1表示完全不透明 0表示完全透明
setGeometry 和resize的区别
setGeometry(x,y,w,h)——设置的是主屏幕(不包含标题栏(PS:菜单栏状态栏 还在))
resize——全屏整体移动
绘图
virtual void paintEvent(QPaintEvent *event);
void QDrawView::paintEvent(QPaintEvent *event)
{
QPainter paint(this);
int h = this->height();
int w = this->width();
QRect rect(20,10,100,300);
QPen pen(Qt::SolidLine);
pen.setColor(Qt::red);
paint.setPen(pen);
QBrush brush(Qt::yellow);
paint.setBrush(brush);
paint.drawRect(rect);
QPoint p1(30,30);
QPoint p2(140,450);
paint.drawLine(p1,p2);
}
调色板
QPalette是Qt中的调色板类,它提供的setColor()函数可改变控件的颜色,其原型为:
void QPalette::setColor(ColorRole acr, const QColor &acolor)
其中, ColorRole是个枚举,指的是颜色主题,QPalette::Window是指背景色,QPalette::WindowText指的是前景色, QPalette::Button指的是按钮的底色...
QPalette pal = palette();
pal.setColor(QPalette::Window, Qt::yellow);
pal.setColor(QPalette::ButtonText, Qt::red);
setPalette(pal);
延伸到:setBackgroundRole、setAutoFillBackground
MainWindow的结构分为五个部分:菜单栏(Menu Bar)、工具栏(Toolbars)、停靠窗口(Dock Widgets)、状态栏(Status Bar)和中央窗口(Central Widget).是最常见的窗口形式,可以作为GUI程序的主窗口。
QMainWindow常常被继承,因为这使得封装中央部件、菜单和工具条以及窗口状态条变得更容易,当用户点击菜单项或者工具条按钮时,槽会被调用.
中央窗口可以使用任何形式的widget来填充。1.Qt程序中的主窗口通常具有一个中心窗口部件。一般不建议使中央窗口为空,一般放置在Qworkspace位置。可以使用setCentralWidget()函数来填充中央窗口。
void MainWindow::initview()
{
pView = new QDataView(this);
setCentralWidget(pView);
}
QDataView::QDataView(QWidget *parent) : QWidget(parent)
{
m_pTabWidget = new QTabWidget(this);
m_pShowViewAnalog = new QTableWidget();
m_pShowViewDigital = new QTableWidget();
m_pShowViewNet = new QTableWidget();
m_pShowViewAnalog->setParent(m_pTabWidget);
m_pShowViewDigital->setParent(m_pTabWidget);
m_pShowViewNet->setParent(m_pTabWidget);
m_pTabWidget->addTab(m_pShowViewAnalog,QString("1"));
m_pTabWidget->addTab(m_pShowViewDigital,QString("2"));
m_pTabWidget->addTab(m_pShowViewNet,QString("3"));
m_pTabWidget->setTabPosition(QTabWidget::South);
m_pTabWidget->setCurrentIndex(0);
//用于视图的布局
QGridLayout *mainLayout = new QGridLayout();
mainLayout->addWidget(m_pTabWidget,0,0);
setLayout(mainLayout);
}
菜单栏(QMenuBar)是MainWindow中已经有的,需要是就使用menuBar()函数来返回;也可以通过setMenuBar进行设置。
void MainWindow::intimenubar()
{
QMenuBar *pmenubar = new QMenuBar(this);
QMenu *pmenu = new QMenu(tr("新建"),pmenubar);
pmenu->addAction(tr("关于"));
pmenubar->addMenu(pmenu);
setMenuBar(pmenubar);
}
状态栏(Status Bar)是MainWindow中已经有的,需要是就使用statusBar()函数来返回;
工具栏(QToolBar)通过addToolBar()函数添加到窗口中。
1、定义一个QAction对象,设置显示图标和文字;
2、定义一个QToolBar对象;
3、将QAction对象addAction添加到QToolBar对象中;
4、将QToolBar对象addToolBar添加到待显示的窗口中;
1.setOrientation 设置水平或垂直方向
2.使用布局管理器来设置显示的位置,把工具栏当成一个普通的空间看待即可。
注意:需要在项目中导入新添加的qrc文件(这样目录随之也会被添加进来):
m_aboutAction = new QAction(QIcon(":/res/about.png"), tr("关于"), this);
//或者 m_aboutAction = new QAction(QPixmap(":/res/about.png"), tr("关于"), this);
m_pToolBar = addToolBar(tr("ToolBar"));
m_pToolBar->addAction(m_aboutAction);
connect(m_aboutAction, SIGNAL(triggered()), this, SLOT(aboutSlot()));
或者是
QToolButton *m_about = new QToolButton();
connect(m_about, SIGNAL(clicked()), this, SLOT(aboutSlot()));
m_about->setIcon(QIcon(":/res/about.png"));
m_about->setToolTip("关于");
m_pToolBar->addWidget(m_about);
注:action是一种不可见的界面元素,主要用于菜单项、工具栏按钮的设计,其action的主要信号时trigger().
停靠窗口需要自己通过addDockWidget()添加。.设置停靠窗口的一般流程如下。
(1)创建一个QDockWidget对象的停靠窗体。
(2)设置此停靠窗体的属性,通常调用setFeatures()及setAllowedAreas()两种方法。
(3)新建一个要插入停靠窗体的控件,常用的有QListWidget和QTextEdit。
(4)将控件插入停靠窗体,调用QDockWidget的setWidget()方法。
(5)使用addDockWidget()方法在MainWindow中加入此停靠窗体。
QDockWidget *dw1 = new QDockWidget(QString("停靠窗口1"), this);//构建停靠窗口,指定父类
dw1->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable);//设置停靠窗口特性,可移动,可关闭
dw1->setAllowedAreas(Qt::LeftDockWidgetArea);//设置可停靠区域为主窗口左边和右边
QTextEdit *dte = new QTextEdit("DockWindow First");
dw1->setWidget(dte);
addDockWidget(Qt::LeftDockWidgetArea, dw1);
QMainWindow常用的函数
1.setCentralWidget()设置中心区域
2.statusBar()获取状态栏
QStatusBar 的 addPermanentWidget:永久添加显示
addWidget
insertWidget
3.addToolBar() 添加工具栏
用到QWidget 的 addActions
removeAction
insertAction
QDialog 是对话框窗口的基类。对话框主要用来执行短期任务,或与用户进行互动,它可以是模态的也可以是非模态的。QDialog 没有菜单栏、工具栏、状态栏等。
m_pbutton = new QDialogButtonBox;
m_pbutton->addButton(tr("确定"), QDialogButtonBox::AcceptRole);
m_pbutton->addButton(tr("取消"),QDialogButtonBox::RejectRole);
connect(m_pbutton, SIGNAL(accepted()), this, SLOT(OnOK()));
connect(m_pbutton, SIGNAL(rejected()), this, SLOT(OnCancel()));
1.好像没有直接通过代码生成对话框的。先在c++ class 基于Qwidget生成 ,再把基类从Qwidget改成QDialog,最后补上析构函数。
class QAboutDialog : public QDialog
{
Q_OBJECT
public:
explicit QAboutDialog(QWidget *parent = 0);
};
QAboutDialog::QAboutDialog(QWidget *parent) : QDialog(parent)
{
setWindowTitle(tr("关于"));
setWindowIcon(QIcon(":/res/about.png"));
setFixedSize(350,100);
}
2.通过可视化ui生成对话框。
模态对话框:exec()
注意:在new 的方式生成对话框时。在对话框单击按钮或关闭对话框时,即如(模态对话框,exec()函数返回后),对话框只是隐藏(缺省的),而并没有从内存中删除。可以使用delete 删除对话框对象,释放内存。
非模态对话框:show()
调用setAttribute(Qt::WA_DeleteOnClose); 关闭时自动删除,释放内存。
可通过事件触发,如下面的虚函数重写。
virtual void keyPressEvent(QKeyEvent *event);
virtual void keyReleaseEvent(QKeyEvent *event);
virtual void focusInEvent(QFocusEvent *event);
virtual void focusOutEvent(QFocusEvent *event);
virtual void enterEvent(QEvent *event);
virtual void leaveEvent(QEvent *event);
virtual void paintEvent(QPaintEvent *event);
virtual void moveEvent(QMoveEvent *event);
virtual void resizeEvent(QResizeEvent *event);
virtual void closeEvent(QCloseEvent *event);
对话框和主窗口调用关系通过parentwidget(),这样在对话框就可以获取到主窗口了。这个思想是vs的思想,其实还可以通过信号槽机制,实现对话框和主窗口的互动。
如果是主窗口,就使用 QMainWindow;如果是对话框,就是用 QDialog;如果不确定,或有可能作为顶级窗口,也有可能嵌入到其他窗口中,那么使用 QWidget。
需要注意的是,窗口和控件都继承自 QWidget,如果不为控件指定父对象,它就会被作为窗口处理,这时 setWindowTitle() 和 setWindowIcon() 函数就会生效。
基本布局管理器(QBoxLayout)
QWidget::setLayou() 函数可以在一个部件上应用布局管理器
addWidget
addLayout
addStretch:设置固定比例,除去控件占用的区域外,剩余的空间按比例来划分。
addSpacing:如果嫌弃控之间间隙太大,可以使用spacers来填充。
延伸:
sizeHint函数:这个属性所保存的 QSize 类型的值是一个被推荐给窗口或其它组件。不是每个控件,都会自适应占整个父控件空间;有时我们也不需要它一直变大,可以通过以下属性设置大小
QSizePolicy
控件的sizePolicy说明控件在布局管理中的缩放方式。通过调用setSizePolicy设置缩放方式。如果不想控件随窗口大小变化而变化,就把setSizePolicy的参数设置为QSizePolicy::Fixed
m_pAlmgrpLayout_btn = new QHBoxLayout();
// m_pAlmgrpLayout_btn->addStretch(4);
m_paddBtn->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Fixed);
m_pAlmgrpLayout_btn->addWidget(m_paddBtn);
m_pAlmgrpLayout_btn->addSpacing(50);
// m_pAlmgrpLayout_btn->addStretch(1);
m_pAlmgrpLayout_btn->addWidget(m_palterBtn);
// m_pAlmgrpLayout_btn->addStretch(1);
m_pAlmgrpLayout_btn->addWidget(m_pdelBtn);
// m_pAlmgrpLayout_btn->addStretch(1);
m_pAlmgrpLayout_btn->addWidget(m_pokBtn);
// m_pAlmgrpLayout_btn->addStretch(4);
QVBoxLayout *pVLayout_btn = new QVBoxLayout();
pVLayout_btn->addWidget(ToolBar);
pVLayout_btn->addLayout(m_pAlmgrpLayout_btn);
setLayout(pVLayout_btn);
1.布局流程
a.先创建控件,如new QPushButton
b.使用布局管理器添加控件,完成局部的布局 如 QGridLayout、QHBoxLayout 、QVBoxLayout 调用addWidget
c.使用布局管理器把所有的局部布局整合起来。如 QGridLayout、QHBoxLayout 、QVBoxLayout 调用addLayout
d.调用setLayout 设置全局的布局管理器显示
1.addTab
2.insertTab
3.removeTab
4.setTabPosition //设置tab页的位置方向
5.setCurrentWidget
6.currentChanged 为信号 重点使用,切换tab触发该信号
1.setEditTriggers(QAbstractItemView::NoEditTriggers); 将表格变为禁止编辑
2.setSelectionBehavior(QAbstractItemView::SelectRows); //整行选中的方式
3.setSelectionMode(QAbstractItemView::SingleSelection ); //设置为选中单个目标
4.对于水平或垂直方法的表头,可以用以下方式进行 隐藏/显示 的设置
行:horizontalHeader()->setVisible(false);
列:verticalHeader()->setVisible(false);
QHeaderView::sectionResized//信号,用于处理响应改变列表头的大小宽度
5.在单元格里加入控件:
setCellWidget
6.设置行高、列宽
1. tableWidget->setColumnWidth(3,200);
2. tableWidget->setRowHeight(3,60);
将行和列的大小设为与内容相匹配
tableWidget->resizeColumnsToContents();
tableWidget->resizeRowsToContents();
7.获得单击单元格的内容
cellDoubleClicked
或itemDoubleClicked
8.添加表头内容:
QStringList header;
header<<""<
tableWidget->setHorizontalHeaderLabels(header);
9.setShowGrid(true);//显示表格线
10.setColumnHidden //设置隐藏列
11.设置垂直滚动条响应
QScrollBar *bar = verticalScrollBar(); connect((QObject*)bar,SIGNAL(valueChanged(int)),this,SLOT(getvalue(int)));
12.int nScrollBarHeight=this->maximumViewportSize().height();//!获取滚动条的滚动范围
13.设置每个item 显示内容
QTableWidgetItem
1.单元格设置字体颜色和背景颜色 及字体字符、对齐方式
item = new QTableWidgetItem(str);
item->setTextAlignment(Qt::AlignHCenter);
setItem(iItem,iColumn,item);
item->setBackgroundColor(clrBKCur);
item->setTextColor(clrTextCur);
2. setdata()函数设置自定义的数据,该数据是不显示在界面上的,但与单元格相关联的。
使用控件,如需特别设置控件的样式可以使用setStyleSheet来实现。
QListWidget
子项:QListWidgetItem
其QListWidgetItem常见的函数:setSelected、setHidden、setText、setFlags
addItem
QTreeWidget
右键弹出菜单
指定控件的右键菜单策略,然后把右键点击信号和某个槽函数连接。
1.设置控件的右键菜单策略setContextMenuPolicy(Qt::CustomContextMenu);
2.把控件的右键点击信号和槽函数连接。信号是customContextMenuRequested
3.槽函数实现创建菜单QMenu,并添加addAction子项QAction
4.菜单调用exec(QCursor::pos());弹出菜单
public slots:
void popmenuslot(QPoint point);
pmodel2 = new QStandardItemModel();
ptableView2 = new QTableView();
ptableView2->setModel(pmodel2);
ptableView2->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ptableView2, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(popmenuslot(QPoint)));
void QDataView::popmenuslot(QPoint point)
{
QMenu *pMenu = new QMenu(this);
QAction *mes = new QAction(tr("信息"), this);
QAction *quit = new QAction(tr("退出"), this);
/* 添加菜单项 */
pMenu->addAction(mes);
pMenu->addAction(quit);
/* 在鼠标右键处显示菜单 */
pMenu->exec(cursor().pos());
}
MVC 由三种对象组成。Model是应用程序对象,View是它的屏幕表示,Controller定义了用户界面如何对用户输入进行响应
Model:
所有的item models都基于QAbstractItemModel类,这个类定义了用于views和delegates访问数据的接口。
数据本身不必存储在model,数据可被置于一个数据结构或另外的类,文件,数据库,或别的程序组件中。
如果它基于table或list形式的数据结构,最好从QAbstractListModel,QAbstractTableModel开始做起
View:
QListView把数据显示为一个列表,QTableView把Model 中的数据以table的形式表现,QTreeView 用具有层次结构的列表来显示model中的数据。这些类都基于QAbstractItemView抽象基类.
QTableWidget是QTableView的子类,主要的区别是QTableView可以使用自定义的数据模型来显示内容(也就是先要通过setModel来绑定数据源),而QTableWidget则只能使用标准的数据模型,并且其单元格数据是QTableWidgetItem的对象来实现的(也就是不需要数据源,将逐个单元格内的信息填好即可)。这主要体现在QTableView类中有setModel成员函数,而到了QTableWidget类中,该成员函数变成了私有。使用QTableWidget就离不开QTableWidgetItem。QTableWidgetItem用来表示表格中的一个单元格,正个表格都需要用逐个单元格构建起来。
qt用于项(item)的组件有两类:
1.item views,包括qlistview、qtreeview、qtableview、qcolumnview等。 都是基于模型/视图(model/view)结构。
2.item widgets,包括qlistwidget、qtreewidget、qtreewidget、qtablewidget.都是直接将数据存储在每一项。
1.需要在主窗口工作区放置一个QMdiArea作为子窗口的容器,类似相当于tabwidget。可以在QMainWindow 中调用setcentralwidget,使QMdiArea作为中央窗口。或者把QMdiArea当成一个普通的widget。
2.QMdiArea重要的函数有
1.QMdiSubWindow *addSubWindow(QWidget *widget, Qt::WindowFlags flags = Qt::WindowFlags());
2.QMdiSubWindow *currentSubWindow() const;
3. QMdiSubWindow *activeSubWindow() const;
4.QList
5. void cascadeSubWindows(); //窗口级联
6.void closeActiveSubWindow();//窗口平铺
7.void setViewMode(ViewMode mode); enum ViewMode { SubWindowView, TabbedView };
8.void closeAllSubWindows();
信号
Q_SIGNALS:
void subWindowActivated(QMdiSubWindow *); //活动窗口切换时发射该信号
//在这个例子里,mdiarea作为一个普通的widget控件存放。
void MainWindow::initview()
{
pView = new QDataView(this);
setCentralWidget(pView);
}
mdiArea = new QMdiArea(this);
//用于视图的布局
QGridLayout *mainLayout = new QGridLayout();
mainLayout->addWidget(m_pTabWidget,0,0);
mainLayout->addWidget(ptableView1,0,2);
mainLayout->addWidget(ptableView2,0,3);
mainLayout->addWidget(pDrawView,0,4);
mainLayout->addWidget(mdiArea,0,1);
mainLayout->setColumnMinimumWidth(0,200);
mainLayout->setColumnMinimumWidth(2,200);
mainLayout->setColumnMinimumWidth(3,200);
void MainWindow::mdislot()
{
mdiwidget *pwidget = new mdiwidget(this); //
if(pView)
{
pView->mdiArea->addSubWindow(pwidget); //文档窗口添加到MDI
pwidget->show(); //在单独的窗口中显示
}
}
void MainWindow::colsemdislot()
{
if(pView)
{
pView->mdiArea->closeAllSubWindows();
}
}
//弹出窗口
void MainWindow::PopWidgetslot()
{
mdiwidget* pwidget = new mdiwidget(this);
pwidget->setAttribute(Qt::WA_DeleteOnClose); //关闭时自动删除
pwidget->setWindowTitle("基于QWidget的窗体,无父窗口,关闭时删除");
pwidget->setWindowFlag(Qt::Window,true);
pwidget->setWindowOpacity(0.9);
pwidget->show();
}
//内嵌窗口,使用QTabWidget让widget内嵌在tab页上。
void MainWindow::InsideWidgetslot()
{
mdiwidget* pwidget = new mdiwidget(this);
pwidget->setAttribute(Qt::WA_DeleteOnClose); //关闭时自动删除
if(pView)
{
if(pView->m_pTabWidget)
{
int ncur = pView->m_pTabWidget->addTab(pwidget,QString("tab"));
pView->m_pTabWidget->setCurrentIndex(ncur);
pView->m_pTabWidget->setVisible(true);
}
}
}
QSettings 注册表的信息读写
1. void setValue(const QString &key, const QVariant &value);
2. QVariant value(const QString &key, const QVariant &defaultValue = QVariant()) const;
QCryptographicHash 加密算法类
QString QDlgLogin::encrypt(const QString &str){
//字符串MD5算法加密
QByteArray btArray;
btArray.append(str);//加入原始字符串
QCryptographicHash hash(QCryptographicHash::Md5); //Md5加密算法
hash.addData(btArray); //添加数据到加密哈希值
QByteArray resultArray =hash.result(); //返回最终的哈希值
QString md5 =resultArray.toHex();//转换为16进制字符串
return md5;
}
splash 窗口:用于程序启动时的启动窗口,从QDialog继承过来。
contextMenuEvent:虚函数,用于右键弹出菜单。
widget.ui:如果使用ui,则会有窗体界面文件,即如widget.ui,这个文件是自动生成的,存储窗体每个组件的属性设置和布局。其实就是一个xml文件。
ui_widget.h :是对widget.ui文件编译后自动生成的。出现在编译后的目录下。是一个与ui文件widget.ui对应的类定义文件。
会在类的头文件自动定义一个指针 Ui::Widget *ui; 后面访问控件都是通过指针ui. 所以构造函数会有ui->setupui(this); 析构函数有:delete ui;