Qt的一些用法(1-10)

本文介绍了Qt库中的一些关键功能,如跨线程调用、QGraphicsItem的鼠标旋转、响应子控件大小变化、全局应用对象的使用以及QTextEdit的最大长度限制。通过示例代码展示了如何实现这些功能,包括使用QCoreApplication::postEvent进行线程间通信,自定义GraphicsEllipseItem实现鼠标旋转效果,以及通过事件过滤器捕获QTextEdit的按键事件。此外,还探讨了如何设置QTreeView表头不显示省略号,并重写QToolBox样式。文章提供了丰富的代码示例,帮助读者深入理解Qt编程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、使用插件的好处?

二、跨线程调用函数?How can I invoke functions on QObjects from another thread?

方法1:void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority = Qt::NormalEventPriority)
方法2:使用信号和槽函数

三、如何鼠标旋转QGraphicsItem?

1、GraphicsEllipseItem

#ifndef GRAPHICSELLIPSEITEM_H
#define GRAPHICSELLIPSEITEM_H

#include <QGraphicsEllipseItem>
#include <QPointF>
#include <QGraphicsSceneMouseEvent>
class GraphicsEllipseItem : public QGraphicsEllipseItem
{
public:
    GraphicsEllipseItem()
    {
        _rotation = 0;
        setFlags(flags() | QGraphicsItem::ItemIsSelectable);
    }
    void mousePressEvent(QGraphicsSceneMouseEvent *event)
    {
        initialPos = mapToScene(event->pos());
        QGraphicsItem::mousePressEvent(event);
    }

    void mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
        QPointF pos = mapToScene(event->pos());
        if (pos.y() > initialPos.y()) {
            ++_rotation;
        } else {
            --_rotation;
        }
        if(1){
            QTransform xform;
            xform.rotate(_rotation);
            setTransform(xform);
        }
        else {
            setRotation(_rotation);
        }
        initialPos = pos;
    }

protected:
    QPointF initialPos;
    qreal _rotation;
};

#endif // GRAPHICSELLIPSEITEM_H

2、GraphicsView

#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H

#include <QGraphicsView>
#include "graphicsellipseitem.h"
class GraphicsView : public QGraphicsView
{
public:
    GraphicsView(){
        QGraphicsScene *scene = new QGraphicsScene();
          setScene(scene);
          GraphicsEllipseItem *item1 = new GraphicsEllipseItem();
          item1->setRect(-40, -30, 80, 60);
          scene->addItem(item1);
    }
};

#endif // GRAPHICSVIEW_H

3、main

#include "mainwindow.h"

#include <QApplication>
#include "graphicsview.h"
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    GraphicsView box;
    box.show();
    return app.exec();
}

四、如何在子控件大小变化时候,动态变化父类控件?

方法1. 设置子控件的sizeHint(),当子空间变化时,对父控件进行重新布局
方法2. 设置子控件setFixedSize()

参考代码

1、Label

#include <QWidget>
#include <QLabel>
class Label : public QLabel {
    Q_OBJECT
public:
    Label(const QString &text, QWidget *parent) : QLabel(text, parent)
     {
         changeSize = false;
         setAutoFillBackground(true);
         QPalette pal = palette();
         pal.setColor(QPalette::Window, Qt::red);
         setPalette(pal);
     }

    QSize sizeHint() const
    {
        if(changeSize) {
            return QSize(400, 400);
        } else {
            return QLabel::sizeHint();
        }
    }
    void setChangedSize(bool value)
      {
          changeSize = value;
      }
private:
    bool changeSize;
};

2、 Widget

#include <QWidget>
#include <QTimer>
#include <QVBoxLayout>
class Widget : public QWidget {
    Q_OBJECT
public:
    Widget()
    {
        label = new Label("Hello World", this);
        QLabel *label2 = new QLabel("Standard label", this);
        label2->setAutoFillBackground(true);
        QPalette pal = label2->palette();
        pal.setColor(QPalette::Window, Qt::blue);
        label2->setPalette(pal);
        QVBoxLayout *layout = new QVBoxLayout(this);
        layout->addWidget(label);
        layout->addWidget(label2);
        QTimer::singleShot(2000, this, SLOT(testSlot()));
    }
public slots:
    void testSlot()
    {
        if(0)
        {
            label->setFixedSize(400,400);
        }
        else {
            QSize oldSize = label->size();
            label->setChangedSize(true);
            if(oldSize.width() < label->sizeHint().width() ||
                    oldSize.height() < label->sizeHint().height()) {
                label->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
                label->updateGeometry();
            } else {
                label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
                label->updateGeometry();
            }
        }
    }
private:
    Label *label;
};

3、 main

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Widget widget;
    widget.resize(200,200);
    widget.show();
    return app.exec();
}

五、全局应用对象

qApp or QCoreApplication::instance()

六、如何获得、设置QTextEdit 最大长度

绑定信号contentsChanged, 计算出toPlainText().length()长度,限制输入。

七、按键消息,重复触发keyReleaseEvents,keyPressEvents如何解决?

使用isAutoRepeat来判断

  void keyPressEvent(QKeyEvent *event)  
   {
       if (event->isAutoRepeat()) {    
           qDebug() << "keyPressEvent ignore";
           event->ignore();   
       } else {    
           qDebug() << "keyPressEvent accept";
           event->accept();
       }  
   }  

八、使用eventFilter过滤,捕获消息

  class MainWindow : public QMainWindow
  {
  public:
      MainWindow();

  protected:
      bool eventFilter(QObject *obj, QEvent *ev) override;

  private:
      QTextEdit *textEdit;
  };

  MainWindow::MainWindow()
  {
      textEdit = new QTextEdit;
      setCentralWidget(textEdit);

      textEdit->installEventFilter(this);
  }

  bool MainWindow::eventFilter(QObject *obj, QEvent *event)
  {
      if (obj == textEdit) {
          if (event->type() == QEvent::KeyPress) {
              QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
              qDebug() << "Ate key press" << keyEvent->key();
              return true;
          } else {
              return false;
          }
      } else {
          // pass the event on to the parent class
          return QMainWindow::eventFilter(obj, event);
      }
  }

九、如何使QTreeView表头不出现省略号。

  • setResizeMode(relevantColumn, QHeaderView::ResizeToContents)
  • setStretchLastSection(false)

十、QCommonStyle重写QToolBox的样式

class MyStyle : public QCommonStyle {
public:

   MyStyle() : QCommonStyle() {}
   void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter,
                    const QWidget *widget = nullptr) const override
   {
       if (element == CE_ToolBoxTab) {
           const QStyleOptionToolBox *tb = qstyleoption_cast<const QStyleOptionToolBox *>(option);
           painter->save();
           painter->setBrush(QBrush(Qt::darkBlue));
           painter->drawRoundedRect(option->rect.x() + 10, option->rect.y(), option->rect.width() - 20,
                                    option->rect.height(), 10.0, 5.0);
           painter->setPen(Qt::white);
           painter->drawText(option->rect.x() + 15, option->rect.y() + 15, tb->text);
           painter->restore();
       } else {
           return QCommonStyle::drawControl(element, option, painter, widget);
       }
   }
};
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    a.setStyle(new MyStyle);
    QToolBox tb;
    tb.addItem(new QPushButton("A"), "Test");
    tb.addItem(new QPushButton("B"), "Test 2");
    tb.show();
    return a.exec();
}

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值