QT入门

离线下载安装

http://download.qt.io/archive/qt/

设计器

从设计工具栏中拖动控件到窗口上,objectName就是对应的控件,调用方式ui->pushButton->setText("i am a button");

 

中英文

cpp文件中加入execution_character_set("utf-8")

cpp文件另存为utf-8 bom。cpp文件本来默认创建出来的也是utf-8的,但是编译之后依然乱码,notepad++打开cpp文件,设置编码为utf-8 bom就好了

 

控件

动态创建的控件resize设置大小,move设置控件在父窗口中的位置。如果显示不出来试一下调用show(),子窗口中不需要show()

一般用QWidget当作容器,一层一层嵌套。QWidget中的背景色会从那个父窗口中继承,要调用setAutoFillBackground(true);阻止自己的背景色被父窗口覆盖,auto fill background就是自己画自己的背景。

 

窗口
this->setWindowFlags(Qt::FramelessWindowHint);//去除边框

protected:

void resizeEvent(QResizeEvent* event);继承窗口大小改变的事件

this->close();//关闭窗口

不记得哪里copy的代码了,用来实现无边框的缩放,缩放时鼠标样式也改变

void cusWin::judgeRegionSetCursor(const QPoint& currentPoint)
{
    // 获取窗体在屏幕上的位置区域,tl为topleft点,rb为rightbottom点
    QRect rect = this->rect();
    QPoint tl = mapToGlobal(rect.topLeft());
    QPoint rb = mapToGlobal(rect.bottomRight());

    int x = currentPoint.x();
    int y = currentPoint.y();

    if (tl.x() + Padding >= x && tl.x() <= x && tl.y() + Padding >= y && tl.y() <= y) {
        // 左上角
        dir = LEFTTOP;
        this->setCursor(QCursor(Qt::SizeFDiagCursor));  // 设置鼠标形状
    }
    else if (x >= rb.x() - Padding && x <= rb.x() && y >= rb.y() - Padding && y <= rb.y()) {
        // 右下角
        dir = RIGHTBOTTOM;
        this->setCursor(QCursor(Qt::SizeFDiagCursor));
    }
    else if (x <= tl.x() + Padding && x >= tl.x() && y >= rb.y() - Padding && y <= rb.y()) {
        //左下角
        dir = LEFTBOTTOM;
        this->setCursor(QCursor(Qt::SizeBDiagCursor));
    }
    else if (x <= rb.x() && x >= rb.x() - Padding && y >= tl.y() && y <= tl.y() + Padding) {
        // 右上角
        dir = RIGHTTOP;
        this->setCursor(QCursor(Qt::SizeBDiagCursor));
    }
    else if (x <= tl.x() + Padding && x >= tl.x()) {
        // 左边
        dir = LEFT;
        this->setCursor(QCursor(Qt::SizeHorCursor));
    }
    else if (x <= rb.x() && x >= rb.x() - Padding) {
        // 右边
        dir = RIGHT;
        this->setCursor(QCursor(Qt::SizeHorCursor));
    }
    else if (y >= tl.y() && y <= tl.y() + Padding) {
        // 上边
        dir = UP;
        this->setCursor(QCursor(Qt::SizeVerCursor));
    }
    else if (y <= rb.y() && y >= rb.y() - Padding) {
        // 下边
        dir = DOWN;
        this->setCursor(QCursor(Qt::SizeVerCursor));
    }
    else {
        // 默认
        dir = NONE;
        this->setCursor(QCursor(Qt::ArrowCursor));
    }
}

void cusWin::mouseReleaseEvent(QMouseEvent *event)
{
    if (event->button() == Qt::LeftButton) {
        isLeftPressDown = false;
        if (dir != NONE) {
            this->releaseMouse();
            this->setCursor(QCursor(Qt::ArrowCursor));
        }
    }
}
void cusWin::mousePressEvent(QMouseEvent *event)
{
    switch (event->button()) {
    case Qt::LeftButton:
        isLeftPressDown = true;
        if (dir != NONE) {
            this->mouseGrabber();
        }
        else {
            dragPosition = event->globalPos() - this->frameGeometry().topLeft();
        }
        break;
    default:
        QWidget::mousePressEvent(event);
    }
}
void cusWin::mouseMoveEvent(QMouseEvent *event)
{
    QPoint gloPoint = event->globalPos();
    QRect rect = this->rect();
    QPoint tl = mapToGlobal(rect.topLeft());
    QPoint rb = mapToGlobal(rect.bottomRight());

    if (!isLeftPressDown) {
        this->judgeRegionSetCursor(gloPoint);
    }
    else {

        if (dir != NONE) {
            QRect rMove(tl, rb);

            switch (dir) {
            case LEFT:
                if (rb.x() - gloPoint.x() <= this->minimumWidth())
                    rMove.setX(tl.x());
                else
                    rMove.setX(gloPoint.x());
                break;
            case RIGHT:
                rMove.setWidth(gloPoint.x() - tl.x());
                break;
            case UP:
                if (rb.y() - gloPoint.y() <= this->minimumHeight())
                    rMove.setY(tl.y());
                else
                    rMove.setY(gloPoint.y());
                break;
            case DOWN:
                rMove.setHeight(gloPoint.y() - tl.y());
                break;
            case LEFTTOP:
                if (rb.x() - gloPoint.x() <= this->minimumWidth())
                    rMove.setX(tl.x());
                else
                    rMove.setX(gloPoint.x());
                if (rb.y() - gloPoint.y() <= this->minimumHeight())
                    rMove.setY(tl.y());
                else
                    rMove.setY(gloPoint.y());
                break;
            case RIGHTTOP:
                rMove.setWidth(gloPoint.x() - tl.x());
                rMove.setY(gloPoint.y());
                break;
            case LEFTBOTTOM:
                rMove.setX(gloPoint.x());
                rMove.setHeight(gloPoint.y() - tl.y());
                break;
            case RIGHTBOTTOM:
                rMove.setWidth(gloPoint.x() - tl.x());
                rMove.setHeight(gloPoint.y() - tl.y());
                break;
            default:
                break;
            }
            this->setGeometry(rMove);
        }
        else {
            move(event->globalPos() - dragPosition);
            event->accept();
        }
    }
    QWidget::mouseMoveEvent(event);
}

 

qss,不需要特定的文件,只需要css格式的字符串,习惯用XXX.qss存放样式,然后读取文件内容设置stylesheet

#include "mainwindow.h"
#include <QApplication>
#include <QFile>
#include <QStyleFactory>
#include <QTextStream>
#include <QFontDatabase>
#include "cuswin.h"

bool setSkin(QApplication* const app, QString const &skinFile)
{
    QFile file(skinFile);

    if (QFile::exists(skinFile) && file.open(QIODevice::ReadOnly))
    {
        qDebug("get file ");
        QApplication::setStyle(QStyleFactory::create("Windows"));
        QString strTemp;
        QTextStream in(&file);
        while (!in.atEnd())
        {
            strTemp.append(in.readLine());
        }
        file.close();
        app->setStyleSheet(strTemp);
        //qDebug("style sheet %s", qPrintable(strTemp));
    }
    else
    {
#ifdef Q_WS_MAC
        qDebug("%s: %s: File does not exist %s... setting mac style...",
               __FILE__, __FUNCTION__, qPrintable(skinFile));
        app->setStyle(new QMacStyle());
        return true;
#else
        qDebug("%s: %s: File does not exist or failed to open %s",
               __FILE__, __FUNCTION__, qPrintable(skinFile));
        return false;
#endif
    }

    return true;
}

void setFont()
{
    // 添加字体文件
        int fontId = QFontDatabase::addApplicationFont("E:\\res\\PingFang Medium.ttf" );
        QStringList fontFamilies = QFontDatabase::applicationFontFamilies(fontId);

        QFont font;
        if (fontFamilies.size() > 0)
        {
            font.setFamily(fontFamilies.at(0));
            font.setPixelSize(14);
        }

        QApplication::setFont(font);

}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    //读取qss格式的文件,设置通用样式
    setSkin(&a, "E:/test.qss");
    //设置通过用字体,可以使用路径当参数
    setFont();

    MainWindow w;
    w.show();

    w.show();

    return a.exec();
}

//qss文件
QPushButton{
	color: red
}

QScrollBar:vertical{
    max-width:6px;
	min-width:6px;
    background:rgba(255,255,255,255);
    margin:0px,0px,0px,0px;
    padding-top:0px;   
    padding-bottom:0px;
}

QScrollBar::sub-line:vertical{
     border: none;
     background: none;
     height: 50px;
     subcontrol-position: bottom;
     subcontrol-origin: margin;
}

QScrollBar::add-line:vertical{
     border: none;
     background: none;
     height: 50px;
     subcontrol-position: bottom;
     subcontrol-origin: margin;
}

QScrollBar::handle:vertical
{
    min-width:6px;
	max-width:6px;
    background:rgba(0,0,0,25%);
    border-radius:3px; 
    min-height:40;
}

也可以单个部件设置样式

bPushButton->setStyleSheet("background:#494e52");

QLabel实现鼠标点击事件

connect(pClose, SIGNAL(clicked(QMouseEvent*)), this, SLOT(closeButtonClicked(QMouseEvent*)));

默认是不支持的,需要重写,然后触发点击事件

 

qlabelex.h//QLAbelEx

#ifndef QLABELEX_H
#define QLABELEX_H

#include <QLabel>

class QLabelEx : public QLabel
{
    Q_OBJECT
public:
    explicit QLabelEx(QWidget *parent = nullptr);

protected:
    void mouseReleaseEvent(QMouseEvent *ev);  //抬起
    void mousePressEvent(QMouseEvent *ev);    //按下
    void mouseDoubleClickEvent(QMouseEvent *ev);  //双击
    void mouseMoveEvent(QMouseEvent *ev);     //拖动

signals:
    void clicked(QMouseEvent *ev);  //抬起
    void pressed(QMouseEvent *ev);  //按下
    void doubled(QMouseEvent *ev);  //双击
    void moved(QMouseEvent *ev);    //拖动

public slots:
};

#endif // QLABELEX_H

qlabelex.cpp//QLabelEx

#include "QLabelEx.h"

QLabelEx::QLabelEx(QWidget *parent) : QLabel(parent)
{
}

void QLabelEx::mouseReleaseEvent(QMouseEvent *ev)
{
    emit clicked(ev);
}

void QLabelEx::mousePressEvent(QMouseEvent *ev)
{
    emit pressed(ev);
}

void QLabelEx::mouseDoubleClickEvent(QMouseEvent *ev)
{
    emit doubled(ev);
}

void QLabelEx::mouseMoveEvent(QMouseEvent *ev)
{
    emit moved(ev);
}

mainwindow中再实现closeButtonClicked


public slots:
    void closeButtonClicked(QMouseEvent*);

void cusWin::closeButtonClicked(QMouseEvent* pEvent)
{
    this->close();
}

顺便带上自己的closebutton样式,要先设置objectName为closeButton

#closeButton{
	border-image:url(/res/gray_close.png);
}

#closeButton:hover{
	border-image:url(/res/login_close_focus.png);
}

聊天气泡,内容自适应

void cusWin::initChatList()
{
    pChatList = new QListWidget(this);
    pChatList->move(350, 70);
    pChatList->resize(width() - 350, height() - 76);

    for (int i = 0; i < 30; ++i)
    {
        int yPos = 10;
        QWidgetEx *widget=new QWidgetEx(this);
        QLabel *pAvatar = new QLabel(widget);
        QPixmap pixMap("e:\\res\\defaultUser.png");
        QPixmap pixMap2 = pixMap.scaled(40, 40, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
        pAvatar->setPixmap(pixMap2);
        pAvatar->move(10, yPos);
        pAvatar->resize(40, 40);
        pAvatar->setStyleSheet("border-radius:10px");


        QLabel *pNickName = new QLabel(widget);
        pNickName->setText("好名字都被狗取了");
        pNickName->move(60, yPos);

        yPos += 20;
        QChatBG *pChat = new QChatBG(widget);
        pChat->setObjectName("chatItemPanel");
        pChat->resize(220, 200);
        pChat->move(60, yPos);

        QTextEdit *pMsg = new QTextEdit(pChat);
        pMsg->setFontPointSize(12);
        pMsg->setText("巴扎嘿and其德隆东墙,我是一只小小鸟,小啊小小鸟,巴扎嘿");
        pMsg->move(10, 6);
        pMsg->resize(170, 88);
        pMsg->setObjectName("chatItemMsg");
        pMsg->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        pMsg->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
        pMsg->setMaximumWidth(170);

        QTextCursor cursor = pMsg->textCursor();
        QTextImageFormat imageFormat;

        imageFormat.setWidth( 24);
        imageFormat.setHeight( 24);
        imageFormat.setName("e:\\res\\emoji\\xiao.png");
        cursor.insertImage(imageFormat);

        //connect(widget, SIGNAL(sizeChanged(QWidget*)), this, SLOT(lineWidthChanged(QWidget*)));

        yPos += pChat->height() + 100;
        QListWidgetItem *item = new QListWidgetItem();
        QSize size = item->sizeHint();
        item->setSizeHint(QSize(280, yPos));

        pChatList->addItem(item);
        widget->resize(280, yPos);
        pChatList->setItemWidget(item, widget);
    }

    pChatList->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
    pChatList->verticalScrollBar()->setSingleStep(10);
    pChatList->setObjectName("chatList");


    //pChatList->show();
}

void cusWin::lineWidthChanged(QWidget* pWidget)
{
    //qDebug("line width changed %d", pWidget->width());
    QChatBG* pChatBg = pWidget->findChild<QChatBG*>("chatItemPanel");
    QTextEdit* pMsg = pChatBg->findChild<QTextEdit*>("chatItemMsg");

    QTextDocument *document = pMsg->document();
    document->setTextWidth(pWidget->width() - 90);
    //document->adjustSize();

    if(document)
    {
        QTextEdit *editor=qobject_cast<QTextEdit*>(document->parent()->parent());
        if(editor)
        {
            int newwidth = document->idealWidth() + 10;//10
            int newheight = document->size().height() + 20;//20
            //qDebug("width %f %f %f", document->textWidth(), document->idealWidth(), document->indentWidth());
            if(newwidth != editor->width())
            {
                editor->setFixedWidth(newwidth);
            }

            if(newheight != editor->height())
            {
                editor->setFixedHeight(newheight);
            }

            editor->parentWidget()->setMinimumHeight(newheight);
            editor->parentWidget()->setMaximumHeight(newheight);

            editor->parentWidget()->setMinimumWidth(newwidth + 20);
            editor->parentWidget()->setMaximumWidth(newwidth + 20);

            pWidget->setMaximumHeight(newheight + 40);
            pWidget->setMinimumHeight(newheight + 40);
        }
    }


}

//QListWidget中每一行作为一条消息,消息框目前是可编辑的用来测试,为了实现气泡效果,我重写了一个QWidget用来画背景

#ifndef QCHATBG_H
#define QCHATBG_H

#include <QWidget>
#include <QPainter>

class QChatBG : public QWidget
{
    Q_OBJECT
public:
    explicit QChatBG(QWidget *parent = nullptr);

public:
    void setBackColor(QColor color);

signals:

public slots:

protected:
    void paintEvent(QPaintEvent *event);

private:
    QColor m_color;
};

#endif // QCHATBG_H

cpp文件,主要拉伸气泡,左上角、左下角、右上角、右下角不拉伸,其他地方拉伸,QWidget的子QWidget的背景色继承。设置背景图片失败了,才刚学qt不想深究。索性自己画

#include "qChatBG.h"
#include <QColormap>
#include <QPalette>

QChatBG::QChatBG(QWidget *parent) : QWidget(parent)
{
    m_color= Qt::transparent;
}

void QChatBG::setBackColor(QColor color)
{
    m_color = color;
}

void QChatBG::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);

    int left = 20, top = 40;
    QPixmap bg(width(), height());
    //bg.fill(m_color);

    bg.fill(m_color);//默认Qt::transparent

    QPainter p(&bg);
    QPixmap pixMap_b("e:\\res\\left_chat_bg.png");//气泡图片的路径

    //左上
    QRect dRect(0, 0, left, top);
    QRect sRect(0, 0, left, top);
    p.drawPixmap(dRect, pixMap_b, sRect);

    //左中
    dRect.setRect(0, top, left, height() - pixMap_b.height());
    sRect.setRect(0, top, left, 1);
    p.drawPixmap(dRect, pixMap_b, sRect);

    //左下
    dRect.setRect(0, height() - (pixMap_b.height() - top), left, pixMap_b.height() - top);
    sRect.setRect(0, top, left, pixMap_b.height() - top);
    p.drawPixmap(dRect, pixMap_b, sRect);

    //中上
    dRect.setRect(left, 0, width() - pixMap_b.width(), top);
    sRect.setRect(left, 0, 1, top);
    p.drawPixmap(dRect, pixMap_b, sRect);

    //中间
    dRect.setRect(left, top,  width() - pixMap_b.width(), height() - pixMap_b.height());
    sRect.setRect(left, top, 1, 1);
    p.drawPixmap(dRect, pixMap_b, sRect);

    //中下
    dRect.setRect(left, height() - (pixMap_b.height() - top), width() - pixMap_b.width(), pixMap_b.height() - top);
    sRect.setRect(left, top, 1, pixMap_b.height() - top);
    p.drawPixmap(dRect, pixMap_b, sRect);

    //右上
    dRect.setRect(width() - (pixMap_b.width() - left), 0, pixMap_b.width() - left, top);
    sRect.setRect(left, 0, pixMap_b.width() - left, top);
    p.drawPixmap(dRect, pixMap_b, sRect);

    //右中
    dRect.setRect(width() - (pixMap_b.width() - left), top, pixMap_b.width() - left, height() - pixMap_b.height());
    sRect.setRect(left, top, pixMap_b.width() - left, 1);
    p.drawPixmap(dRect, pixMap_b, sRect);

    //右下
    dRect.setRect(width() - (pixMap_b.width() - left), height() - (pixMap_b.height() - top), pixMap_b.width() - left, pixMap_b.height() - top);
    sRect.setRect(left, top, pixMap_b.width() - left, pixMap_b.height() - top);
    p.drawPixmap(dRect, pixMap_b, sRect);

    painter.drawPixmap(QPointF(0, 0), bg);
}

气泡图片

白色背景看不出来

设置QListWidget动态显示:鼠标进入的时候显示,鼠标出去的时候隐藏,重写QListWidget

h文件,继承enter、leave

#ifndef QLISTWIDGETEX_H
#define QLISTWIDGETEX_H

#include <QListWidget>
#include <QScrollBar>

class QListWidgetEx : public QListWidget
{
public:
    QListWidgetEx(QWidget *parent);

protected:
    void enterEvent(QEvent *event);
    void leaveEvent(QEvent *event);
};

#endif // QLISTWIDGETEX_H

cpp文件,动态显示

#include "qlistwidgetex.h"

QListWidgetEx::QListWidgetEx(QWidget *parent) : QListWidget(parent)
{

}

void QListWidgetEx::enterEvent(QEvent *event)
{
    //verticalScrollBar()->show();
    setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
}

void QListWidgetEx::leaveEvent(QEvent *event)
{
    //verticalScrollBar()->hide();
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}

脱离qtcreator运行qt程序

双击运行编译出来的程序的时候,会报一堆库找不到的错误

qt命令行执行windeployqt d2.exe可以自动复制qt依赖到程序目录
**注意命令行的选择要和编译器的选择一致,比如都选择MinGW_32bit,选岔了会出现各种问题,吃过亏**

只会复制qt的依赖库,不要妄想复制第三方的库,

**我电脑上装过Strawberry,里面有libstdc++-6.dll,运行qt的时候提示什么找不到定位点,qt自己的工具应该不会复制错误,所以应该是链接到其他库了,我一个库一个库的删除,发现是添加libstdc++-6.dll之后才提示的定位点的错误,执行where libstdc++-6.dll发现居然有两个地方有这个库,然后把这两个路径从环境变量中删掉**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值