目录
Qwidget总介
QWidget是Qt中所有用户界面对象的基类,主要用于界面显示。QWidget的底层机制是由QPaintDevice和QPaintEngine组成的。而QPaintDevice是一个抽象类,提供了绘制设备的接口,QPaintEngine也是一个抽象类,提供了绘制引擎的接口。所以Qwidget是主要用于界面显示和事件处理方面的,具体作用如下所示:
- 它可以作为一个顶层窗口,也可以作为一个子窗口,通过设置父对象和窗口标识来控制。
- 已可以设置各种属性,如大小、位置、字体、样式表、工具提示、窗口图标、窗口标题等。
- 已可以接收鼠标、键盘和其他窗口事件,并根据事件类型调用相应的槽函数。
- 它可以创建和使用信号和槽机制,实现对象之间的通信和交互。
- 它可以作为其他控件的基类,如按钮、文本框、单选框等,实现更多的功能和效果。
其中,QPaintDevice是一个二维空间的抽象,这个二维空间允许QPainter在其上面进行绘制,也就是QPainter工作的空间。QPaintEngine提供了画笔(QPainter)在不同的设备上进行绘制的统一的接口。
那么我们接着来说一说QWidget的子类,QWidget有很多子类,如QPushButton、QLabel、QLineEdit、QTextEdit、QCheckBox、QRadioButton等等。这些咱们都可以在如下的左边工具栏找到。
一般C++里面只需要拖动控件就能实现简单的界面设计,在这里我主要提一哈python里面的QT怎么使用Qwidget。
使用QWidget创建GUI界面的步骤如下:https://zhuanlan.zhihu.com/p/434909621
PyQT的Qwidget的使用
- 创建一个QWidget对象,它是pyqt5中所有的图形用户界面的基类。
- 设置窗口标题、大小和位置。
- 调用QWidget对象的show()方法将创建的窗口显示出来。
- 最后,调用应用程序对象的exec_()方法来运行程序的主循环,并使用sys.exit()方法确保程序能够完美的退出。
这里是一个简单的,用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_())
Qwidget的另类用法
另外,由于某些工程项目的需要,我们往往会对控件进行提升,比如这里的QPushbutton
我们可以将其提升到其他类型,诸如以下的比如QMenu
另外Qwidget还提供了互相调用的且实例化的路径,就比如说咱们要从一个软件页面跳转到另一个软件页面的时候,就可以将通过新建一个QWidget页面来实现,原来的Qmainwindow也是继承的Qwidget,所以主页面能调动子页面。
就比如说这里:我设计了两个页面,一个是登陆界面,一个是主程序页面
我们可以自定义一个从Qwidget继承的类,重写其paintEventO事件,利用Qt的绘图功能绘制组件外观并实现需要的其他功能。你可以在QtDesigner中将一个Qwidget提升为你自定义的类,或者其他的类,如QMainWindow 、QDialog等,以便使用更多的属性和方法。也可以使用样式表、信号和槽、事件过滤器等技术来改变Qwidge的外观和行为。
如果要重写paintEvent,我们需要以下几个步骤:
- 在你的Qwidget子类的头文件中声明一个虚函数槽void paintEvent(QPaintEvent *event)。
- 在你的Qwidget子类的源文件中定义这个函数,并在函数体中实例化一个QPainter对象,指定this为绘图设备。
- 使用QPainter对象的各种方法来设置画笔、画刷、字体等属性,并调用drawXXX()函数来绘制你想要的内容。
- 如果需要,你还可以使用setRenderHint()函数来设置抗锯齿等效果,或者使用translate()、save()、restore()等函数来移动或保存画家状态。
Qwidget C++示例
这里是我的登录界面的代码:
#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"取消");
}
}
这是我主程序的代码,主要是一个简单的opencv灰度变换,还有文件夹创建,选择等常用操作。
#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;
}
具体详情可以参考我的这篇博客
QT与Opencv的联合应用_qt联合opencv_Helloorld_1的博客-CSDN博客
以上就是我目前对Qwidget的理解!!!