The ultimate use of Qt's Qwidget! ! !

Table of contents

Introduction to Qwidget

Use of PyQT's Qwidget

Alternative usage of Qwidget

 Qwidget C++ example

Introduction to Qwidget

        QWidget is the base class of all user interface objects in Qt, mainly used for interface display. The underlying mechanism of QWidget is composed of QPaintDevice and QPaintEngine. QPaintDevice is an abstract class that provides an interface to a drawing device, and QPaintEngine is also an abstract class that provides an interface to a drawing engine. Therefore, Qwidget is mainly used for interface display and event processing, and its specific functions are as follows:

  • It can be used as a top-level window or as a child window, controlled by setting the parent object and window ID.
  • It is already possible to set various properties such as size, position, font, style sheet, tooltip, window icon, window title, etc.
  • Can receive mouse, keyboard and other window events, and call the corresponding slot function according to the event type.
  • It can create and use signal and slot mechanism to realize communication and interaction between objects.
  • It can be used as the base class of other controls, such as buttons, text boxes, radio buttons, etc., to achieve more functions and effects.

        Among them, QPaintDevice is an abstraction of a two-dimensional space. This two-dimensional space allows QPainter to draw on it, which is the space where QPainter works. QPaintEngine provides a unified interface for brushes (QPainter) to draw on different devices.

        Then let's talk about the subclasses of QWidget. QWidget has many subclasses, such as QPushButton, QLabel, QLineEdit, QTextEdit, QCheckBox, QRadioButton and so on. These can all be found on the left toolbar as follows.

Here is QT's official documentation on QWidget

Generally, in C++, you only need to drag the control to realize a simple interface design. Here I mainly mention how to use Qwidget in QT in python.

The steps to create a GUI interface using QWidget are as follows: https://zhuanlan.zhihu.com/p/434909621

Use of PyQT's Qwidget

  1. Creates a QWidget object, which is the base class for all GUIs in pyqt5.
  2. Set window title, size and position.
  3. Call the show() method of the QWidget object to display the created window.
  4. Finally, call the application object's exec_() method to run the program's main loop, and use the sys.exit() method to ensure that the program exits gracefully.

Here is a simple code for a login screen written in pyqt:

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QLineEdit, QPushButton

class Login(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('Login')
        self.resize(300, 150)

        self.username_label = QLabel('Username:', self)
        self.username_label.move(50, 30)
        self.username_input = QLineEdit(self)
        self.username_input.move(120, 30)

        self.password_label = QLabel('Password:', self)
        self.password_label.move(50, 70)
        self.password_input = QLineEdit(self)
        self.password_input.setEchoMode(QLineEdit.Password)
        self.password_input.move(120, 70)

        self.login_button = QPushButton('Login', self)
        self.login_button.move(120, 110)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    login = Login()
    login.show()
    sys.exit(app.exec_())

Alternative usage of Qwidget

        In addition, due to the needs of some engineering projects, we often improve the controls, such as the QPushbutton here

 We can promote it to other types, such as the following such as QMenu

        In addition, Qwidget also provides a mutual calling and instantiation path. For example, when we want to jump from one software page to another software page, we can create a new QWidget page to achieve it. The original Qmainwindow is also inherited. Qwidget, so the main page can mobilize subpages.

 For example here: I designed two pages, one is the login interface and the other is the main program page

        We can customize a class inherited from Qwidget, rewrite its paintEventO event, use Qt's drawing function to draw the appearance of the component and realize other functions needed. You can promote a Qwidget to your custom class in QtDesigner, or other classes, such as QMainWindow, QDialog, etc., in order to use more properties and methods. You can also use techniques such as style sheets, signals and slots, and event filters to change the appearance and behavior of Qwidge.

If we want to rewrite paintEvent, we need the following steps:

  • Declare a virtual function slot void paintEvent(QPaintEvent *event) in the header file of your Qwidget subclass.
  • Define this function in the source file of your Qwidget subclass, and instantiate a QPainter object in the function body, specifying this as the drawing device.
  • Use various methods of the QPainter object to set properties such as pens, brushes, fonts, etc., and call the drawXXX() function to draw what you want.
  • If necessary, you can also use the setRenderHint() function to set anti-aliasing and other effects, or use functions such as translate(), save(), restore() to move or save the painter state.

 Qwidget C++ example

        Here is the code of my login screen:

#include "mywindows.h"
#include "ui_mywindows.h"
#include <QDebug>
#pragma execution_character_set("utf-8")//加上这个后,下面代码中使用中文就不会报错
#include "opencv_basic.h"
#include "ui_opencv_basic.h"
#include <QMessageBox>

mywindows::mywindows(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::mywindows)
{
    ui->setupUi(this);
}

mywindows::~mywindows()
{
    delete ui;
}

/*
        //输入信号,触发方式,执行任务
        this->w=new enter;//实例化页面二
        connect(ui->pushButton,&QPushButton::clicked,[=]{
            this->hide();//隐藏当前页面;还没有释放
            this->w->show();//显示页面2
        });
*/

void mywindows::on_pushButton_clicked()
{
    QString username= ui->lineEdit->text();
    QString password= ui->lineEdit_2->text();
    if(username==QString ("1") && password==QString("1"))//设置密码
    {
        qDebug() <<u8"登录成功";
       this->A=new opencv_basic;//实例化页面二
        this->hide();//隐藏当前页面;还没有释放
        this->A->show();//显示页面2
    }
    else
    {
        qDebug() <<u8"登录失败" ;
        QWidget *parent=new QWidget;
        QMessageBox::information(parent,u8"提示",u8"密码输入错误",u8"确定",u8"取消");
    }
}

        This is the code of my main program, which is mainly a simple opencv grayscale transformation, as well as common operations such as folder creation and selection.

#include "opencv_basic.h"
#include "ui_opencv_basic.h"
#include <QDir>
#include <QDebug>
#include <iostream>
#include <QString>//字符串转换操作
#include <QMessageBox>//添加警告框
#include <QFileDialog>//添加自选文件夹
#pragma execution_character_set("utf-8")

opencv_basic::opencv_basic(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::opencv_basic)
{
    ui->setupUi(this);
    //on_pushButton_clicked();
}

QString path = "F:/test_images/";

opencv_basic::~opencv_basic()
{
    delete ui;
}

int i=0;


//读取绝对路径下的第一张图片的路径并且返回
std::string file_read(int &i)
{
/*可以读取绝对路径下的第一张图片*/
//获取应用程序可执行文件的文件路径:    //QDir::currentPath();//获取当前工程目录
QDir dir(path);
QStringList filename ;
filename << "*.png" << "*.jpg";//可叠加,可使用通配符筛选
QStringList results;
results = dir.entryList(filename,QDir::Files | QDir::Readable,QDir::Name);

//增加一个判定
int a=results.size();
//qDebug()<<a;打印出来有几张图片
qDebug()<<"i"<<i;
if(i+1>a)
{
    QWidget *parent=new QWidget;
    QMessageBox::information(parent,u8"提示",u8"图片读取错误",u8"确定",u8"取消");
    qDebug()<<i;
    i--;//回到上一张
}

//qDebug()<<results;//results里就是获取的所有文件名了,这里的qdebug是将运行的路径进行输出
QString st=results.at(i);
QString rt=path;
qDebug()<<rt+st;
std::string str1=rt.toStdString();
std::string str2 = st.toStdString();
std::string str3=str1+str2;
return str3;
}

//这个函数是显示原图,值得注意的是,在转化8位3通道的图像时,OpenCV和QImage使用的红蓝通道是相反的,需要使用rgbSwapped方法互换一下
void opencv_basic::on_pushButton_clicked()
{
    std::string str3=file_read(i);
    cv::Mat srcimage=cv::imread(str3);
    /*--------------------------------------------------------*/
   // cv::Mat srcimage=cv::imread("../opencv_basic/2.jpg");
    //cv::imshow("原始图片",src);R
    //Mat转QImage 像素   oldlabel放置原图
       QImage disimage = QImage(srcimage.data,srcimage.cols,srcimage.rows,srcimage.cols*srcimage.channels(),QImage::Format_RGB888);
       QImage imag =disimage.rgbSwapped();//将红蓝通道对换
       disimage = imag.scaled(ui->label->width(),ui->label->height(),Qt::KeepAspectRatio);
       ui->label->setPixmap(QPixmap::fromImage(disimage));
}

//这个函数是对图像进行模糊化和灰度化
void opencv_basic::on_pushButton_2_clicked()
{
    std::string str3=file_read(i);
    cv::Mat srcimage=cv::imread(str3);
    //cv::imshow("原始图片",src);
    cv::Mat img_resize,img_Gray,img_blur;
    //cv::resize(srcimage, img_resize,cv::Size(), 0.5, 0.5);
    cvtColor(srcimage, img_Gray, cv::COLOR_BGR2GRAY);
    GaussianBlur(img_Gray, img_blur, cv::Size(3, 3), -1, -1);//高斯模糊化

    //Mat转QImage 像素   oldlabel放置原图
      // QImage disimage = QImage(img_blur.data,img_blur.cols,img_blur.rows,img_blur.cols*img_blur.channels(),QImage::Format_Grayscale8);
    //Mat转QImage 像素   oldlabel放置灰度图
    QImage disimage = QImage(img_blur.data,img_blur.cols,img_blur.rows,img_blur.cols*img_blur.channels(),QImage::Format_Grayscale8);
    ui->label_2->setPixmap(QPixmap::fromImage(disimage.scaled(ui->label_2->width(),ui->label_2->height(),Qt::KeepAspectRatio)));//,Qt::KeepAspectRatio在后面加上这个就可以保证图片不变形
}

//下一张的按键
void opencv_basic::on_pushButton_4_clicked()
{
    i++;
    file_read(i);
}

//上一张的按键
void opencv_basic::on_pushButton_5_clicked()
{
    i--;
    if(i<=0)
    {
        i=0;
    }
    file_read(i);
}

//增加一个警告框用来提示是否存在文件夹,如果没有就创建
void opencv_basic::on_pushButton_3_clicked()
{
       QDir *temp = new QDir;
       bool exist = temp->exists("F:/test_images");
       if(exist)
        {// QMessageBox::warning(this,"创建文件夹","文件夹已经存在!");//会显示中文乱码
          QMessageBox::information(this,u8"提示",u8"创建成功",u8"确定",u8"取消");
       }
       else
       {
           bool ok = temp->mkdir("F:/test_images");
           if( ok )
              // QMessageBox::warning(this,"创建文件夹","文件夹创建成功!");
           QMessageBox::information(this,u8"提示",u8"创建失败!",u8"确定",u8"取消");
       }

}

void opencv_basic::on_action_triggered()
{
    path = QFileDialog::getExistingDirectory(this,"请选择要打开文件路径","./");
    qDebug()<<"filename : "<<path;
}

For details, please refer to my blog

Joint application of QT and Opencv_qt joint opencv_Helloorld_1's Blog-CSDN Blog

The above is my current understanding of Qwidget! ! !

Guess you like

Origin blog.csdn.net/Helloorld_1/article/details/131951689