现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

Qt界面设计总结

2014-09-02 18:18 工业·编程 ⁄ 共 9266字 ⁄ 字号 暂无评论

1. 子窗体或控件,重写paintEvent事件,画边框、背景、文字、图片效果比较好。用paintEvent 事件画边框,用QPalette设置背景。

// 画边框

    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing, true);

    painter.setPen(QPen(QColor(225,70,56), 2));

//    painter.setBrush(QColor(16,62,81));   // 也可设置背景,有时效果不好

    painter.drawRoundedRect(rect(), 5.0, 5.0);

// 设置背景

    QPalette pal = palette();

    pal.setBrush(QPalette::Window, QColor(16,62,81));

    setPalette(pal);

    setAutoFillBackground(true);

2. 继承QDialog,想让对话框以模态运行,使用exec(),继承时使用setWindowFlags()后则达不到模态的效果。不知道原因。

3. QStringList 输出

QStringList m_strLang << "English"

                                          << "Chinese";

qDebug("set language: %s", m_strLang.at(0).toLocal8Bit().constData());

4. QStringList 使用注意

    QStringList strDateformatList;

    strDateformatList

            << m_strMonth + "-" + m_strDay + "-" + m_strYear

            << m_strDay + "-" + m_strMonth + "-" + m_strYear

            << m_strYear + "-" + m_strMonth + "-" + m_strDay

            ;

如果strDateformatList 在生命周期内多次调用,则会多次插入字符串,使得字符串重复,这不是我们想要的。那就定义为局部变量,每次会重新赋值,达到更新的目的。

5.需要动态重新的页面可以在showEvent函数中重新。

6. 用paintEvent或用调色板为QWidget填充背景时,需要加上setAutoFillBackground(true);语句,否则没效果。

7. 想使弹出的窗口为圆角,用paintEvent画圆角矩形,但四个直角仍然存在,不美观。可以把背景设为透明,用paintEvent画出想要的背景,因为四个角没有画上背景,是透明的,所以看不见。

     // 设置背景为透明 (构造函数中)

    QPalette pal = palette();

    pal.setBrush(QPalette::Window, QColor(255, 255, 255, 0));

    setPalette(pal);

    setAutoFillBackground(true);

    // 画背景和边框 (paintEvent函数中)

    QPainter painter(this);

    painter.setRenderHint(QPainter::Antialiasing, true);

    painter.setPen(QPen(QColor(225,70,56), 2));

    painter.setBrush(QColor(16,62,81));

    painter.drawRoundedRect(rect(), 5.0, 5.0);

8. Qt::Key_Enter、Qt::Key_Reture

Qt::Key_Enter对应小键盘的Enter键

Qt::Key_Return对应大键盘的Enter键

9. 事件过滤。窗口部件的事件到达目的地之前提前获取并处理相关事件,实现个性化的处理。

我在QLabel对象中放入两个QPushButton对象和两个QLabel对象,QPushButton实现值的调节,其中一个QLabel对象用于显示值,一个QLabel对象用于显示标题。类似SpinBox。在多个SpinBox上点击实现焦点切换,当鼠标点到QPushButton上时,QPushButton处理了mousePressEvent事件,所以无法实现焦点切换。为两个QPushButton对象安装事件过滤器,然后在其父部件中处理eventFilter函数

m_btnLeft->installEventFilter(this);

m_btnRight->installEventFilter(this);

//安装事件过滤器后,传给m_btnLeft、m_btnRight的事件会首先发送给eventFilter函数

bool ESpinBoxItem::eventFilter(QObject*obj,QEvent*ev)

{

if(obj == m_btnLeft || obj == m_btnRight)

{

if(ev->type() == QEvent::MouseButtonPress)

{

emit sign_spinBoxPressed(m_nItem);

return true; // 不传给目标对象处理

}

}

return false; // 不处理的事件则传给目标对象处理

}

10. 拍照动画

使用QTimeLine和QGraphicsPixmapItem对象,当时间线帧改变时,设置QGraphicsPixmapItem的位置,实现动画效果。

// 在QGraphicsView构造函数中

// take photo animation

    m_timerAnimation = new QTimeLine(900);

    m_timerAnimation->setCurveShape(QTimeLine::LinearCurve);

    m_timerAnimation->setFrameRange(0, 240);

    m_pixmapUpAnimation = QPixmap(":/images/animation.png");

    m_pixmapDownAnimation = QPixmap(":/images/animation.png");

    m_upPixmapItem = new QGraphicsPixmapItem;

    m_downPixmapItem = new QGraphicsPixmapItem;

    m_upPixmapItem->setZValue(4);

    m_downPixmapItem->setZValue(4);

    m_upPixmapItem->setPos(0, 0);            // 左上角为原点

    m_downPixmapItem->setPos(0, 240);

    scene()->addItem(m_upPixmapItem);

    scene()->addItem(m_downPixmapItem);

    m_upPixmapItem->hide();

    m_downPixmapItem->hide();

    connect(m_timerAnimation, SIGNAL(frameChanged(int)), this, SLOT(slot_playAnimation(int)));

// 槽函数

void EGraphicsView::slot_playAnimation(int nFrame)

{

    m_upPixmapItem->show();

    m_downPixmapItem->show();

    qDebug("nFrame: %d", nFrame);

    if(nFrame < 120)

    {

        m_upPixmapItem->setPixmap(m_pixmapUpAnimation.scaled(320, nFrame));

        m_downPixmapItem->setPixmap(m_pixmapDownAnimation.scaled(320, nFrame));

        m_downPixmapItem->setPos(0, 240 - nFrame);

    }

    else

    {

        m_upPixmapItem->setPixmap(m_pixmapUpAnimation.scaled(320, 240 - nFrame));

        m_downPixmapItem->setPixmap(m_pixmapDownAnimation.scaled(320, 240 - nFrame));

        m_downPixmapItem->setPos(0, nFrame);

    }

}

11.在移动设备上使用渐变或使用渐变的图片时,会出现条纹状,达不到效果。在初始化QApplication对像前调用下面的语句则可以达到效果:

QApplication::setColorSpec(QApplication::ManyColor); //the right choice for applications that use thousands of colors

QApplication app(argc, argv,  QApplication::GuiServer );

12.用setStyleSheet设置背景图片

m_labelButton->setStyleSheet("background-image: url(:images/shutdown/slider.png); background-repeat: no-repeat;"); //注意,不加background-repeat: no-repeat可能会出现透视,很丑。QLabel对象可用setPixmap设置象素图。

13.使对话框圆角

    //构造函数中

    setAutoFillBackground(true);

    QPalette pal = palette();

    pal.setColor(QPalette::Window, QColor(0, 0, 0, 0));

    setPalette(pal);

    //paintEvent函数中

   QPainter painter(this);

   painter.setRenderHint(QPainter::Antialiasing,true);

   painter.setPen(QPen(Qt::red,2));

   painter.setBrush(QColor(16,62,81));

   painter.drawRoundedRect(rect(),5.0,5.0);

// 圆角处有杂色,原因不祥

14. 对某些默认事件的处理修改

正常情况下,按下Tab键,被QWidget看成是去移动键盘焦点,但少数窗口部件需要自行解释。

bool MyClass::event(QEvent *e)

{

         if(e->type() == QEvent::KeyPress)

         {

                 QKeyEvent *ke = (QKeyEvent *)e;

                 if(ke->key() == Qt::Key_Tab)

                  {

                            //这里是特定的Tab处理

                            k->accept();

                            return TRUE;

                  }

         }

         else if(e->type()  >= QEvent::User)

         {

                 // 这里是自定义事件处理

                 return TRUE;

          }

          QWidget::event(e);

}

   15.QLabel继承QFrame,有QFrame的特性。如setFrameStyle(int)可设置QLabel的FrameStyle(框架类型)

FrameStyle有两种:

a.第一种是frameshape:

有以下几种类型:

Constant

Value

Description

QFrame::NoFrame

0

QFrame draws nothing

QFrame::Box

0x0001

QFrame draws a box around its contents

QFrame::Panel

0x0002

QFrame draws a panel to make the contents appear raised or sunken

QFrame::StyledPanel

0x0006

draws a rectangular panel with a look that depends on the current GUI style. It can be raised or sunken.

QFrame::HLine

0x0004

QFrame draws a horizontal line that frames nothing (useful as separator)

QFrame::VLine

0x0005

QFrame draws a vertical line that frames nothing (useful as separator)

QFrame::WinPanel

0x0003

draws a rectangular panel that can be raised or sunken like those in Windows 95. Specifying this shape sets the line width to 2 pixels. WinPanel is provided for compatibility. For GUI style independence we recommend using StyledPanel instead.

b.第二种是frameshadow

有以下几种类型:

Constant

Value

Description

QFrame::Plain

0x0010

the frame and contents appear level with the surroundings; draws using the paletteQPalette::WindowText color (without any 3D effect)

QFrame::Raised

0x0020

the frame and contents appear raised; draws a 3D raised line using the light and dark colors of the current color group

QFrame::Sunken

0x0030

the frame and contents appear sunken; draws a 3D sunken line using the light and dark colors of the current color group

组合值的效果图:

15.几种位置信息

x()、y()、pos()函数都是获得整个窗体左上角的坐标位置。需frameGeometry与geometry相对应,frameGemometry()是获得整个窗体的左上顶点和长、宽值,需geometry()函数获得的是窗体内中央域的左上顶点坐标以及长、宽值。直接调用width()和height()函数获得的是中央区域的长和宽的值。还有两个函数rect()、size(),调用它们获得的结果也都是对于窗体的中央区域而言的。size()获得的是窗体中央区域的长、宽值,rect()与geometry()一样返回一个QRect对象。其中,两个函数获得的长宽、值是一样的,都是窗体中央区域的长、宽值,只是左上顶点的坐标值不一样,geometry()获得的左上角顶点坐标是相对于父窗体而言的坐标,,而rect()获得的左上角顶点坐标始终为(0, 0)。

效果图:

窗体在左上角时:

16.几种输入对话框。

a.获取文本对话框

QString strName =QInputDialog::getText(this,tr("User Name"),tr("Please Input New Name:"),QLineEdit::Normal,m_labelName->text(),&ok);

b.获取项对话框

QStringList list;

list<<tr("男")<<tr("女");

QStringstrSex=QInputDialog::getItem(this,tr("User Sex"),tr("Please Select Sex:"),list,0,false,&ok);

c.获取整数对话框

bool ok;

int nAge = QInputDialog::getInteger(this, tr("User Age"), tr("Please Input Age:"), m_labelAge->text().toInt(), 18, 30, 1, &ok);

if(ok)

{

m_labelAge->setText(QString(tr("%1").arg(nAge)));

}

d.获得双精度对话框

boolok;

double nHeight = QInputDialog::getDouble(this, tr("User Height"), tr("Please Input Height:"), m_labelHeight->text().toDouble(), 160.5, 270.5, 1, &ok);

if(ok)

{

m_labelHeight->setText(QString(tr("%1").arg(nHeight)));

}

17.自定义QMessageBox

    QMessageBox customMsgBox;

customMsgBox.setWindowTitle("Custom message box");

QPushButton *lockButton = customMsgBox.addButton(tr("Lock"), QMessageBox::ActionRole);

QPushButton *unlockButton = customMsgBox.addButton(tr("Unlock"), QMessageBox::ActionRole);

QPushButton *cancelButton = customMsgBox.addButton(QMessageBox::Cancel);

customMsgBox.setIconPixmap(QPixmap(":/images/1.png"));

customMsgBox.setText(tr("This is a custom message box"));

customMsgBox.exec();

if(customMsgBox.clickedButton() == lockButton)

{

m_labelMessage->setText("Custom MessageBox button / lock");

}

else if(customMsgBox.clickedButton() == unlockButton)

{

m_labelMessage->setText("Custom MessageBox button / unlock");

}

else if(customMsgBox.clickedButton() == cancelButton)

{

m_labelMessage->setText("Custom MessageBox button / Cancel");

}

效果图:

定义好的MessageBox

QMessageBox::question

QMessageBox::information

QMessageBox::warning

QMessageBox::critical

QMessageBox::about

QMessageBox::aboutQt

18.在编写程序时,初始化窗体时最好不要使用setGeometry()函数,而用resize()和move()函数代替,因为使用setGeometry()会导致窗体show()之后在错误 的位置上停留很短暂的一段时间,带来闪烁现象。

19.提示错误:E:\vm_shared\study\graphicsview\debug\moc_navibar.cpp:39: error: `staticMetaObject' is not a member of `QGraphicsRectItem'

错误原因:因为QGraphicsRectItem不是QObject的子类,所以在类的声明中不能有Q_OBJECT宏、signal和slot。

20.抓图功能:

// 使用Qt自带的静态函数grabWindow,指定窗体ID,抓图的起启位置和面积大小。

QImage image = QPixmap::grabWindow(QApplication::desktop()->winId(), 0, 0, nDesktopWidth, nDesktopHeight).toImage().scaled(640, 480);

21.视图去掉滚动条

view->setFrameShape(QFrame::NoFrame);

通过布局指定视图的父窗体时,使用上面代码去不掉滚动条。而需要使用view = new QGraphicsView(this);指定父窗体。

最好办法是: view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 一直关掉滚动条

22.QpushButton圆角

QPushButton { border: 2px solid #8f8f91; border-radius: 6px; background-color: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #f6f7fa, stop: 1 #dadbde); min-width: 80px; }

note: 当QPushButton无边框(border: 0px;),有设置背景颜色(background-color: rgb(6,43,58);)时,设置圆角会出现锯齿,因为圆角是边框为圆角,边框大小不能为0px.想让按钮只显示一种颜色(看不见边框颜色),则把边框颜色设为背景色即可。如图:

作者:xiarong715

给我留言

留言无头像?