qt-编程的一些方法_qt tooltips 换行-程序员宅基地

技术标签: Qt  qt  

快速创建多个控件方法。

Button *plusButton = createButton(tr("+"), SLOT(additiveOperatorClicked()));
…
…
Button *Calculator::createButton(const QString &text, const char *member)
{
    Button *button = new Button(text);
    connect(button, SIGNAL(clicked()), this, member);
    return button;
}

多个功能大致相同的方法。例如数字键

for (int i = 0; i < NumDigitButtons; ++i) {
        digitButtons[i] = createButton(QString::number(i), SLOT(digitClicked()));
    }
…
…
void Calculator::digitClicked()
{
    Button *clickedButton = qobject_cast<Button *>(sender());
//do something
}

T qobject_cast ( QObject * object )
本方法返回object向下的转型T,如果转型不成功则返回0,如果传入的object本身就是0则返回0。

在使用时有两个限制:

1# T类型必须继承自QObject。

2#在声明时必须有Q_OBJECT宏。

多个界面用到同一功能的窗体,例如:键盘、导航栏

可以创建一个功能窗体,然后采用窗体控件提升的方法。

* 选择文件/文件夹的对话框:QFileDialog。选择目录的是:QFileDialog::getExistingDirectory(this);
* Combobox :下拉按钮大小,通过样式去设置。:drop-down
* 背景颜色应该是在窗体的一个widget中,不要直接在窗体中设置颜色。
* widget作为一个窗体的全部的时候,可以窗体的全部的边距设置为0;在窗体的Layout属性中。

十进制数格式化,保留两位数

QString MainWindow::toStr(int i)
{
    QString ii = QString("%1").arg(i);
    if(i <= 9)
        return "0"+ii;
    else
        return ii;
}   
* QString("%1:%2PM").arg(h-12,2,10,QChar('0')).arg(min,2,10,QChar('0'));

添加QT的依赖库,可以直接启动qt程序

首先找到这个工具,这个工具叫做“windeployqt”。它一般位于Qt安装目录下的mingw_XX\bin目录下,像我的目录就在C:\ProgramData\Qt\5.8\mingw53_32\bin。

此时,建议将整个目录直接加入系统环境变量,便于后续使用。

确认你的程序是用Qt Creator哪个模式设计的,总共有2个模式,Qt Widgets Application和Qt Quick Application,不同模式下的参数命令是不一样的:

在Qt Widgets Application模式下

输入”windeployqt hello.exe”命令,其中hello.exe是我的程序名称。【完整目录】

Qt Quick Application模式下

输入”windeployqt hello.exe–qmldir”命令,其中hello.exe是我的程序名称,qmldir是你的qml目录,这个目录一般位于mingwXX目录下,像我的目录就在C:\ProgramData\Qt\5.8\mingw53_32\qml。

Qt生成随机数的方法

1.生成随机数

生成随机数主要用到了函数qsrand和qrand,这两个函数在#include  <QtGlobal>中,qsrand用来设置一个种子,该种子为qrand生成随机数的起始值。比如说qsrand(10),设置10为种子,那么qrand生成的随机数就在[10,32767]之间。而如果在qrand()前没有调用过qsrand(),那么qrand()就会自动调用qsrand(1),即系统默认将1作为随机数的起始值。使用相同的种子生成的随机数一样。下列代码生成了[0,9]之间的10个随机数。
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
for(int i=0; i<10; i++)
{
  int test =qrand()%10;
  qDebug()<<test;
} 

template<typename _type>
QStringList MainWindow::getInt(_type f, _type t, int counts)
{
    QStringList vec;
    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
 
    for(int i = 0; i< counts; ++i){
        _type test = f+qrand()/(_type)(RAND_MAX/(t-f));
        vec.push_back(QString("%1").arg(test));
    }
    return vec;
} 

**2.**生成不重复的随机数
这个没有特别好的方法,需要自己手动计算

3.生成递增的随机数

就是在随机数生成后进行排序,Qt提供了一个非常好用的排序函数qSort,详细的用法可参考Qt帮助。

qSort(numbersList.begin(),numbersList.end());

QLabel自动换行的实现,也可手动实现

  1. 让QLabel自适应text的大小,直接用下面的代码:

LabelName->adjustSize();

  1. 让QLabel能够自动判断并换行显示:

LabelName->setGeometry(QRect(328, 240, 329, 27*4)); //四倍行距

LabelName->setWordWrap(true);

LabelName->setAlignment(Qt::AlignTop)

3.QLable等控件垂直显示数据的方法,在每个字符后加\n ,如:截\n距\n设\n置

Qt的QLabel支持HTML的标签语言。例如:

const QString& title = QString("<body><label style=\"color:%1;font:21px 思源黑体 Medium;\">%2</label>"
                               "<label style=\"color:%1;font:15px PingFang SC;\">%3</label>"
                               "<label style=\"color:%1;font:21px PingFang SC;\">%4</label></body>").arg("#FFFFFF").arg("AD").arg("前").arg("测试");

制作多语言包

连接:https://blog.csdn.net/du_bingbing/article/details/52458369;关键词:国际化,中英文,语言包

1.运行lupdate,从应用程序中提取所有经tr()标识过的字符串。生成一个后缀为*.ts的文件。

2.使用Qt Linguist翻译这个*.ts。然后用其生成*.qm。

3.在应用程序中用QTranslator这个类加载*.qm文件

要用lupdate生成后缀为*.ts的文件就要先在应用程序的工程文件*.pro中加入这一句:

TRANSLATIONS= orbitEditor_zh_CN.ts

翻译完后,点File–>Release就可以生成*.qm文件了。在main.cpp中用如下语句加载:

//切换成英文
uint language = pQ7Reader->GetConfigure()->LanguageConfig();
QTranslator translator;
if ( language == zybioLanguage::English )
{
	if ( !translator.load( QCoreApplication::applicationDirPath() + "/translations/en_CN.qm" ) )
	{
		LOG4CXX_INFO( logger, "can't load en_CN.qm file" );
		Msgbox box( MsgboxIcon::warning, QObject::tr( "警告" ), QObject::tr( "加载英文语言包失败"    ) );
		box.exec();
		return -3;
	}
	qApp->installTranslator( &translator );
}
else if( language == zybioLanguage::Chinese )
{
	if(!translator.load( QCoreApplication::applicationDirPath() + "/translations/qt_zh_CN.qm" ))
	{
		Msgbox box( MsgboxIcon::warning, QObject::tr( "警告" ), QObject::tr( "加载中文语言包失败"    ) );
		box.exec();
		return -3;
	}
	qApp->installTranslator( &translator );
}

当然记得把*.qm加入资源文件*.qrc。根据路径的不同,自己修改上面load那句。

这样翻译完后,可能会出现两个问题:

1.Qt的内部类比如QMessageBox,QDialog等中的语句没有翻译成中文。对于这个问题,再加载一个翻译文件就行。Qt已经为我们准备好了,在"安装目录\translations中。我用的就是qt_zh_CN.ts这个文件,Qt已近为我们翻译好了。只要将它导出为*.qm文件就可以加载了。

软件不用重启可以实现多语言的方式:https://blog.csdn.net/lwwl12/article/details/80485123

* 把之前的QTranslator对象保存,可以使用指针的形式
* 在更改语言的时候,把语言给remove。qApp->removeTranslator(m_trans);
* 然后QTranslator对象再次调用load函数,加载新的语言包。
* 然后再qApp->installTranslator(m_trans);
* 然后刷新UI。

ui->retranslateUi(this);

//

备注

* 运行多语言要求要确保运行的系统上有字体文件,就是*.ttf文件,在window上默认就是有的,但是在一些嵌入式ARM版本上,是需要人为的部署进去的。

QT查找同类控件并进行批量处理

例如,一个页面上有很多qpushbotton,都要设置成阴影效果,如果一个一个去设置就会有很多代码,所以可以用如下一种方法去设置,让代码更简洁。如果针对某个对象,对象名objectName可以获取.关键QT方法:findChildren

QList<QPushButton *> Btns = ui->widget->findChildren<QPushButton *>();
foreach (QPushButton * btn, Btns) {
  QGraphicsDropShadowEffect    *shadow_effect = new QGraphicsDropShadowEffect(this);
  shadow_effect->setOffset(0, 6);
  shadow_effect->setColor(QColor(15,98,178));
  shadow_effect->setBlurRadius(10);
  btn->setGraphicsEffect(shadow_effect);
}

当程序存在很多自定义样式的控件时候,可以采用如下几种方法加快开发速度:

  • 把样式表写在qss中
  • 写设置该类控件的样式类(400的开发模式)
  • 把同一类的控件抽离成一个自定义控件,自定义一个类继承该控件,然后实现对应的样式和函数。然后实现提升。

判断QString是否是纯数字:

/* ---示例代码----*/
bool isDigitString(const QString& src) {    
QByteArray ba  = item.toLatin1();//QString 转换为 char*
          const char *s = ba.data();
    while(*s &&  *s>='0' && *s<='9')s++;    return !bool(*s);}
 
/* ---示例代码----*/

QPushButton实现长按的功能

/*
 * +号按下
 */
void MainWindow::on_pushButton_4_pressed()
{
    if(!timer1)
    {
        timer1 = new QTimer();
           connect(timer1,&QTimer::timeout,this,&MainWindow::on_pushButton_4_clicked);
    }
    timer1->start(100);
}
/*
 * 加号释放
 */
void MainWindow::on_pushButton_4_released()
{
    timer1->stop();
}

QPushButton的四种状态样式设置:

QPushButton{
border-image:    url(:/images/FuncWidget/serum.png);
}
QPushButton:focus{
border-image:    url(:/images/FuncWidget/serumdissel.png);
}
 
QPushButton:disabled{
border-image:    url(:/images/FuncWidget/serumdis.png);
}
QPushButton:checked{
border-image:    url(:/images/FuncWidget/serumdown.png);
}

对数字的处理函数:QFloat16

可以四舍五入

可以判断是否为数字

打印和打印预览:QPrinter

setOrientation()告诉QPrinter要使用哪个页面方向。

setPaperSize()告诉QPrinter期望从打印机获得的纸张大小。

setResolution()告诉QPrinter您希望打印机提供什么样的分辨率,单位是点每英寸(DPI)。

setFullPage()告诉QPrinter是要处理整个页面,还是只处理打印机可以绘制的部分。

setCopyCount()告诉QPrinter应该打印多少个文档副本。

Qt编程实现守护程序

  • 在Linux嵌入式的系统中,有个叫做看门狗的程序,当超过阈值时候,就会启动硬件程序复位,这样来帮助和保护程序是出于正常运行状态。在pc端可以编程有个守护程序来实现这个功能,保证程序是在正常运行状态。提供一个软件实现守护进程的办法,原理就是udp通信,单独写个守护进程程序,专门负责检测主程序是否存在,不存在则启动。主程序只需要启动live类监听端口,收到hello就回复ok就行。

为了使得兼容任意程序,特意提炼出来共性,增加了多种设置。

* 可设置检测的程序名称。
* 可设置udp通信端口。
* 可设置超时次数。
* 自动记录已重启次数。
* 自动记录最后一次重启时间。
* 是否需要重新刷新桌面。
* 可重置当前重启次数和最后重启时间。
* 自动隐藏的托盘运行或者后台运行。
* 提供界面设置程序名称已经开启和暂停服务。
* 代码网站:[http://www.qter.org/portal.php?mod=view&aid=776](http://www.qter.org/portal.php?mod=view&aid=776)

去除带有带有小数点的数值,小数点后为0的情况,double float 当小数点后未0则变成int型

    * //double 转QString
QString max;
if(max.lastIndexOf(".0") == max.length() - 2)
{
	max.replace(".0", "");
}

设置Tab键的焦点切换顺序设置

* setTabOrder();

QComboBox等控件,鼠标点击事件等显示不同的响应方法:

* 可以使用事件过滤器,
    * 先注册事件installEventFilter()
    * 再进行响应实现*eventFilter*(QObject*obj,QEvent*ev);   //鼠标点击QEvent::MouseButtonPress

删除容器全部内容;

* qDeleteAll(const Container &c);不需要遍历删除

deleteLater

就是在删除一个对像时,依赖它的子对象,子对象的子对象都会关联地删除。

当我们使用父对象来创建一个对象的时候 ,父对象会把这个对象添加到自己的子对象列表中。当这个父对象被删除的时候,它会遍历它的子对象类表并且删除每一个子对象,然后子对象们自己再删除它们自己的子对象,这样递归调用直到所有对象都被删除。 这种父子对象机制会在很大程度上简化我们的内存管理工作,减少内存泄露的风险。

所以,使用deleteLater主要作用还是减少内存泄露的风险。

设置只能运行一个Qt实例。网址:链接

#include <QSharedMemory>
QSharedMemory    shared("name");//最好使用UUID。
if (shared.attach())
{
   return 0;
}
shared.create(1);
///
//单例运行
const QString sharedKey = "70d67e23-8ef2-44a4-b8f6-027c379fdf44";
int try_n = 3;
while (--try_n > 0)
{
	if(QSharedMemory(sharedKey).attach())
		QThread::sleep(1);
	else
		break;
}
if (try_n == 0)
{
	// 前面进程未退出
	CMessageBox_Dlg    msg(nullptr);
	msg.information(QObject::tr("提示"), QObject::tr("只能运行单个软件"), false); // 这里牺牲多语言
	return 0;
}
QSharedMemory    shared(sharedKey);
if(!shared.create(1))
	return 1

实现程序崩溃生成转储文件

//.pro 文件
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_LFLAGS_RELEASE = $$QMAKE_LFLAGS_RELEASE_WITH_DEBUGINFO
          LIBS += -ldbghelp
//Windows程序崩溃自动转储
#include <WinSock2.h>必须放在Windows.h之前
#include <Windows.h>
#include <DbgHelp.h>
 
#ifdef WIN32
LONG __stdcall ExceptCallBack( EXCEPTION_POINTERS *pExcPointer)
{
    HANDLE hFile = CreateFile(L"CrashDump.dmp", GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL , nullptr);
 
    MINIDUMP_EXCEPTION_INFORMATION loExceptionInfo;
    loExceptionInfo.ExceptionPointers = pExcPointer;
    loExceptionInfo.ThreadId = GetCurrentThreadId();
    loExceptionInfo.ClientPointers = TRUE;
    MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(),hFile, MiniDumpWithFullMemory,    &loExceptionInfo, nullptr, nullptr);
    CloseHandle(hFile);
 
    return EXCEPTION_EXECUTE_HANDLER;
}
 
[[noreturn]] void PureCallHandler(void)
{
    SetUnhandledExceptionFilter(ExceptCallBack);
    throw std::invalid_argument("");  //此处抛出异常,查看调用堆栈排查真正崩溃代码
}
 
[[noreturn]] void InvalidParameterHandler(const wchar_t* expression, const wchar_t* function, const wchar_t* file, unsigned int line, uintptr_t pReserved)
{
    Q_UNUSED(expression) Q_UNUSED(function) Q_UNUSED(file) Q_UNUSED(line) Q_UNUSED(pReserved)
    SetUnhandledExceptionFilter(ExceptCallBack);
    throw std::invalid_argument("");  //此处抛出异常,查看调用堆栈排查真正崩溃代码
}
#endif
 
///使用
    //Windows程序崩溃自动转储
#ifdef WIN32
    SetUnhandledExceptionFilter(ExceptCallBack);
    _set_invalid_parameter_handler(InvalidParameterHandler);
    _set_purecall_handler(PureCallHandler);
#endif

窗体的状态、事件可以通过QEvent去获取。QEvent::WindowDeactivate窗体是否失效

能够自由的拖动的缩放:分裂器。

使用:选择两个控件,然后右键选择布局。

分裂器的例子:“chip”

图片截取方式

QPixmap QPixmap::copy ( const QRect & rectangle = QRect() ) const

QPixmap QPixmap::copy ( int x, int y, int width, int height ) const

用这两个函数,就可以截取一部分图片。

QPixmap:用于显示,使用硬件加速渲染显示。不适应与大图的处理。

QImage:适用于图片处理。

QWidget实现自适应缩放,

QWidget在缩放的时候,会触发

void resizeEvent(QResizeEvent *event)
{
    QSize size =  event->size();
     this->resize() //可以重新自定义大小
}

时间日期控件QDateEditQDateTimeEdit

* 下拉箭头可以通过设置calendarPopup属性去实现.这样会弹出时间和日历表

取对象名转为字符串类型:staticMetaObject

//customPlot项目

QVector<QCPScatterStyle::ScatterShape> shapes;
QCPScatterStyle::staticMetaObject.enumerator(QCPScatterStyle::staticMetaObject.indexOfEnumerator("ScatterShape")).valueToKey(shapes.at(i))

connect的使用

  • 信号转发给信号:
  • connect(ui->tableWidget_pro,SIGNAL(cellClicked(int,int)),this,SIGNAL(cellClicked(int)));
  • 使用lambda表达式
    • connect(dlg, &QDialog::finished, [&](int result) {…});禁止使用该方式的连接,尤其是使用了& 来获取当前类的全部的对象。如果是不获取则是可以考虑使用。
    • connect(dlg, &QDialog::finished, this, [&](int result) {…});替代上面的使用方式,必须要有接收者。但是不建议使用。

原因:第一种方式会导致lambda表达式访问非法内存。因为在当前对象销毁之后,如果sender没有销毁,可以继续发送finished信号,那么在lambda表达式可以继续获取执行,如果表达式内,存在变量的访问。则是会导致访问非法内存。第二种方式可以考虑。但是不建议使用。尤其是lambda表达式内使用了临时变量。如果还留在当前对象(如UI),那么则是会一直触发该lambda表达式。如果使用第二种,必须离开当前作用域时候,调用disconnect。

* 例如:自定义类TableForm,有cellChecked(bool)信号

connect(table,&TableForm::cellChecked,&{…}):

* 在qt中使用信号槽时,有时会想中途断开信号槽的连接,接下来将呈现四种连接断开方法:one:断开明确指定接受对象信号槽,如果连接断开成功返回true,否则返回falsebool  QObject::disconnect(const QObject *sender, const char *signal, const QObject  *receiver, const char *method)two:断开所有连接到对象的信号disconnect(myObject, 0, 0, 0);three:断开所有连接到特定信号disconnect(myObject, SIGNAL(mySignal()), 0,  0);four:断开特定接收器disconnect(myObject, 0, myReceiver, 0);第五个参数代表槽函数在哪个线程中执行 :

1)自动连接(AutoConnection),默认的连接方式,如果信号与槽,也就是发送者与接受者在同一线程,等同于直接连接;如果发送者与接受者处在不同线程,等同于队列连接。

2)直接连接(DirectConnection),当信号发射时,槽函数立即直接调用。无论槽函数所属对象在哪个线程,槽函数总在发送者所在线程执行,即槽函数和信号发送者在同一线程。[这种方式不能跨线程传递消息]

3)队列连接(QueuedConnection),当控制权回到接受者所在线程的事件循环时,槽函数被调用。槽函数在接受者所在线程执行,即槽函数与信号接受者在同一线程。[这种方式既可以在线程内传递消息,也可以跨线程传递消息]

4)锁定队列连接(BlockingQueuedConnection)

Qt::BlockingQueuedConnection:槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。[说明它是专门用来多线程间传递消息的,而且是阻塞的]

5)单一连接(UniqueConnection)

Qt::UniqueConnection:这个flag可以通过按位或(|)与以上四个结合在一起使用。当这个flag设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接

  • 不建议使用默认的形式,一般而言,默认的类型AutoConnection,connect多次也会执行多次槽(即使同一个对象的同一个槽)。推荐使用****UniqueConnection,除非你知道你的连接方式

坐标系转换:QWidget:mapToGlobal()

* 全局坐标系可以转为相对坐标系:mapToGlobal(mouseEvent->pos())
* 某控件相对于当前界面的坐标系:mapTo(this,QPoint(0,0))

按钮的提示性文字:QToolTip

* 可以手动显示void QToolTip::showText()
* 如:QToolTip::showText(mapToGlobal(mouseEvent->pos()),toolTip(),this,rect(),3000);

获取桌面对象:

* QDesktopWidget*desktop=QApplication::desktop();//可以获取桌面大小等等信息

逐行读取【QPlainTextEdit】组件里的字符串

//plainTextEdit的内容逐行添加为comboBox的项
QTextDocument* doc=ui->plainTextEdit->document () ; //文本对象
int cnt=doc->blockCount    () ;//回车符是一个 block
QIcon icon(M:/images/icons/aim.ico");
ui->comboBox->clear();
for (int i=0; i<cnt;i++)
{
  QTextBlock textLine=doc->findBlockByNumber (i)    ; // 文本中的一段
  QString str=textLine.text();
  ui->comboBox->addItem(icon,str);
}

使用QPlainTextEdit自带的快捷菜单

  • 在 UI 设计器里,选择为 plainTextEdit 的customContextMenuRequested()信号生成槽函数,编写如下的代码,就可以创建并显示 QPlainTextEdit 的标准快捷菜单:
void Widget::on_plainTextEdit_customContextMenuRequested(const    QPoint &pos)
{
  //创建并显示标准弹出式菜单
  QMenu* menu=ui->plainTextEdit->createStandardContextMenu();
  menu->exec(pos);
}

设置窗体置顶,并且处于活动状态

show();
raise();
activateWindow();

有用的全局宏的使用

* Q_DISABLE_COPY:禁止拷贝和赋值;可以用于单例的设计。

全屏:

* QApplication::desktop()->width(),QApplication::desktop()->height()
* showFullScreen();
* showMaximized(); //或者其他;取消全屏

隐藏标题栏

* this->setWindowFlags(Qt::FramelessWindowHint|Qt::Dialog);//隐藏标题栏

设置鼠标的形状

* setCursor(Qt::CrossCursor);

设置全局的快捷键:

* 使用第三方库:QxtGlobalShortcut

最小化到托盘:

* QSystemTrayIcon类
//实现最小化
this->hide();
//新建托盘要显示的icon
QIcon icon = QIcon(":/new/prefix1/Cat.png");
//将icon设到QSystemTrayIcon对象中
mSysTrayIcon->setIcon(icon);
//当鼠标移动到托盘上的图标时,会显示此处设置的内容
mSysTrayIcon->setToolTip(tr("OCR"));
//在系统托盘显示此对象
mSysTrayIcon->show();

// 恢复窗体

 //最小化托盘
    connect(mSysTrayIcon.get(), &QSystemTrayIcon::activated,
            [&](QSystemTrayIcon::ActivationReason reason){
                switch(reason){
                    case QSystemTrayIcon::Trigger:
                        //单击托盘图标
                        this->show();
                        break;
                    case QSystemTrayIcon::DoubleClick:
                        //双击托盘图标
                        //双击后显示主程序窗口
                        this->show();
                        break;
                    default:
                        break;
                    }
            });

qDebug()\qInfo()格式化输出

* 可以使用qSetMessagePattern();
* 在项目工程中设置 QT_MESSAGE_PATTERN 环境变量;

QT_MESSAGE_PATTERN 的优先级要比 qSetMessagePattern 的函数调用优先级高

* qDebug()可以实现既在控制台输出内容,又可以在日志log4cxx打印的方式:qInstallMessageHandler()
qInstallMessageHandler(myMessageOutput);
static log4cxx::LoggerPtr g_logger;
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
  QByteArray localMsg = msg.toLocal8Bit();
  switch (type) {
  case QtDebugMsg:
	  LOG4CXX_INFO(g_logger, QString("Debug: %1 (%2:%3, %4)").arg(localMsg.constData()).arg(context.file).arg(context.line).arg(context.function).toStdString());
	  fprintf(stderr, "Debug: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
	  fflush(stderr);
	  break;
//      case QtInfoMsg:
//          LOG4CXX_INFO(g_logger, "Info: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
//          break;
//      case QtWarningMsg:
//          LOG4CXX_INFO(g_logger, "Warning: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
//          break;
//      case QtCriticalMsg:
//          LOG4CXX_INFO(g_logger, "Critical: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
//          break;
//      case QtFatalMsg:
//          LOG4CXX_INFO(g_logger, "Fatal: %s (%s:%u, %s)\n", localMsg.constData(), context.file, context.line, context.function);
//          abort();
  }
}

把一个widget放置在另外一个窗体上面

* 在Q7的lis发送弹窗上实现遮罩层会在lis下面。
* raise()

在一个UI上有多个同类型的控件都是注册事件(QComboBox)

* 在*eventFilter*(QObject*watched,QEvent*event)中对事件进行过滤实现对应的方法。
* 以前的方法一般是多个if…elseif..来实现各个combobox的操作。
* 现在新的方式:
首先先把各个的ComboBox  的数据放在items中,然后各个不同的内容可以使用属性的方式来存储(setProperty())在eventFilter()方法中,如下实现:
if(event->type() == QEvent::MouseButtonPress)
{
	QComboBox *cbox = qobject_cast<QComboBox*>(watched);
	if(!!cbox && zybio::is_element_in_collection(cbox,
				  ui->comboBox_patient_type,    ui->comboBox_department,
				  ui->comboBox_submitter,    ui->comboBox_clinical_diagnosis,
				  ui->comboBox_checker,ui->comboBox_examiner,ui->comboBox_comment))
	{
		const QString& title = cbox->property("title").toString();
		QStringList infoList;
		for(int i = 1; i < cbox->count(); ++i)
			infoList.append(cbox->itemText(i));

		StyledDialog dialog;
		SelectInfo_Dlg* content = dialog.setSubDialog<SelectInfo_Dlg>(    title,    cbox->currentText(), infoList );
		if(dialog.exec() == QDialog::Accepted)
		{
			const auto& list = content->getCheckedBtnData();
			if( !list.isEmpty() )
			{
				   cbox->setCurrentText(list.front());
			}
			else
			{
				   cbox->setCurrentIndex(0);
			}
		}
		return true;
	}

}
///
template< typename _Element >
inline bool is_element_in_collection( _Element const& elem, _Element const& coll )
{
return elem == coll;
}

template<>
inline bool is_element_in_collection< const char* >( const char* const& elem, const char* const& coll )
{
return strcmp( elem, coll ) == 0;
}

template< typename _Element, typename... _Collection >
inline bool is_element_in_collection( const _Element& elem, const _Element& elem0, const _Collection&... coll )
{
return is_element_in_collection( elem, elem0 ) || is_element_in_collection( elem, coll... );
}

template< typename _Element, unsigned int _N >
inline bool is_element_in_collection( _Element const& elem, _Element const( &coll )[ _N ] )
{
static_assert( !std::is_pointer< _Element >::value, "not pointer type" );

return std::any_of( std::cbegin( coll ), std::cend( coll ), [ &elem ]( _Element const& one ){ return elem == one; } );
}

template< typename _Element, typename _Collection >
inline bool is_element_in_collection( _Element const& elem, _Collection const& coll )
{
return std::any_of( coll.begin(), coll.end(), [ &elem ]( _Element const& one ){ return elem == one; } );
}

tablewidget中莫名出现一个可输入的item

* 原因:setRowCount()时候,如果table存在一个焦点,那么则是会触发一些信号,导致tablewidget出现一个可编辑输入的item。
* 解决方法:在调用setRowCount之前把焦点设置到其他控件上。

在模拟态运行一个弹窗,但是没有传入父类时候,可能会导致可以回到父类再次点击出现弹窗

* 对话框是窗口模态,则只在对话框打开时阻止与父窗口的交互。----qt文档

密码框不能正常弹出键盘的问题。

* 在触摸屏触摸点击的情况下,在*mousePressEvent*(QMouseEvent*event)实现调用OSK程序,但是密码框会导致osk无法调用弹出。
* 只能自己实现密码框的显示。来实现

pwdlineedit.h

pwdlineedit.cpp

其他

  1. 修改窗体的名称:setWindowTitle(“myQt program”);//修改程序名

  2. 修改图标:在.pro 文件 。加上:RC_ICONS = cat.ico

  3. QString::fromLocal8Bit()解决中文乱码;# pragma execution_character_set(“utf-8”)

  4. qDebug() 控制台打印。

  5. QMessageBox:: 弹窗。

  6. appendPlainText()  追加文本

  7. 自定义控件

  8. 继承对应的控件。

  9. 不用继承QoBject类

  10. 不用在构造方法中new 一个新的对应控件。因为当其他对象new这个对象时候就已经是new了对应控件

  11. 实现控件的事件

  12. 给控件注册事件:installEventFileter(this);

  13. 重写事件过滤器方法:bool eventFilter(QObject *watched, QEvent *event)

i. 在该方法中,可以通过QMouseEvent *mouse = (QMouseEvent *)event;获取鼠标的键值

ii. (mouse->buttons()&Qt::LeftButton) && event->type()==QEvent::MouseButtonPress ; //获取鼠标的触发方式和键值。

iii. watched == ui->btn_0 && event->type()==QEvent::MouseButtonPress  //获取触发事件的对象和方式

iv. btn = (QPushButton * ) watched; //获取触发事件的对象。

  1. 取得对应的布局管理器(只有通过布局管理器,才能将控件添加到widget/窗体中)
my_btn *btn = new  my_btn(); 
QGridLayout *gridLayout = static_cast<QGridLayout*>(ui->wg_btn->layout());
gridLayout->addWidget(btn,row,col);

或者自己添加管理器:

QWidget *window = new QWidget;
QPushButton *button1 = new QPushButton("One");
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(button1);
window->setLayout(layout);
window->show();
  1. 禁用QSlider和QComboBox的滚动功能

  2. 重载这两个控件:继承QComboBox;然后重新实现wheelEvent() ;可以不做任何处理。

  3. showPopup();显示QComboBox的下拉框内容

qt–setWindowFlags各种标志位的窗口样式

可以设置窗体的各种样式,如关闭按钮、栏目、最小化、还原按钮等等。

Qt 程序获取程序所在路径、用户目录路径、临时文件夹等特殊路径的方法

获取程序所在路径

QString QCoreApplication::applicationDirPath()

如果还想要程序的完整名称

qApp->applicationFilePath()

当前工作目录

QString QDir::currentPath()

如果我们是双击一个程序运行的,那么程序的工作目录就是程序所在目录。

如果是在命令行下运行一个程序,那么运行程序时在命令行的哪个目录,那个目录就是当前目录。

临时文件夹

QStandardPaths类中有各种standardLocations等可以获取临时文件以及其他方式。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/yinsizhilian/article/details/109519201

智能推荐

使用nginx解决浏览器跨域问题_nginx不停的xhr-程序员宅基地

文章浏览阅读1k次。通过使用ajax方法跨域请求是浏览器所不允许的,浏览器出于安全考虑是禁止的。警告信息如下:不过jQuery对跨域问题也有解决方案,使用jsonp的方式解决,方法如下:$.ajax({ async:false, url: 'http://www.mysite.com/demo.do', // 跨域URL ty..._nginx不停的xhr

在 Oracle 中配置 extproc 以访问 ST_Geometry-程序员宅基地

文章浏览阅读2k次。关于在 Oracle 中配置 extproc 以访问 ST_Geometry,也就是我们所说的 使用空间SQL 的方法,官方文档链接如下。http://desktop.arcgis.com/zh-cn/arcmap/latest/manage-data/gdbs-in-oracle/configure-oracle-extproc.htm其实简单总结一下,主要就分为以下几个步骤。..._extproc

Linux C++ gbk转为utf-8_linux c++ gbk->utf8-程序员宅基地

文章浏览阅读1.5w次。linux下没有上面的两个函数,需要使用函数 mbstowcs和wcstombsmbstowcs将多字节编码转换为宽字节编码wcstombs将宽字节编码转换为多字节编码这两个函数,转换过程中受到系统编码类型的影响,需要通过设置来设定转换前和转换后的编码类型。通过函数setlocale进行系统编码的设置。linux下输入命名locale -a查看系统支持的编码_linux c++ gbk->utf8

IMP-00009: 导出文件异常结束-程序员宅基地

文章浏览阅读750次。今天准备从生产库向测试库进行数据导入,结果在imp导入的时候遇到“ IMP-00009:导出文件异常结束” 错误,google一下,发现可能有如下原因导致imp的数据太大,没有写buffer和commit两个数据库字符集不同从低版本exp的dmp文件,向高版本imp导出的dmp文件出错传输dmp文件时,文件损坏解决办法:imp时指定..._imp-00009导出文件异常结束

python程序员需要深入掌握的技能_Python用数据说明程序员需要掌握的技能-程序员宅基地

文章浏览阅读143次。当下是一个大数据的时代,各个行业都离不开数据的支持。因此,网络爬虫就应运而生。网络爬虫当下最为火热的是Python,Python开发爬虫相对简单,而且功能库相当完善,力压众多开发语言。本次教程我们爬取前程无忧的招聘信息来分析Python程序员需要掌握那些编程技术。首先在谷歌浏览器打开前程无忧的首页,按F12打开浏览器的开发者工具。浏览器开发者工具是用于捕捉网站的请求信息,通过分析请求信息可以了解请..._初级python程序员能力要求

Spring @Service生成bean名称的规则(当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致)_@service beanname-程序员宅基地

文章浏览阅读7.6k次,点赞2次,收藏6次。@Service标注的bean,类名:ABDemoService查看源码后发现,原来是经过一个特殊处理:当类的名字是以两个或以上的大写字母开头的话,bean的名字会与类名保持一致public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String C..._@service beanname

随便推点

二叉树的各种创建方法_二叉树的建立-程序员宅基地

文章浏览阅读6.9w次,点赞73次,收藏463次。1.前序创建#include&lt;stdio.h&gt;#include&lt;string.h&gt;#include&lt;stdlib.h&gt;#include&lt;malloc.h&gt;#include&lt;iostream&gt;#include&lt;stack&gt;#include&lt;queue&gt;using namespace std;typed_二叉树的建立

解决asp.net导出excel时中文文件名乱码_asp.net utf8 导出中文字符乱码-程序员宅基地

文章浏览阅读7.1k次。在Asp.net上使用Excel导出功能,如果文件名出现中文,便会以乱码视之。 解决方法: fileName = HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8);_asp.net utf8 导出中文字符乱码

笔记-编译原理-实验一-词法分析器设计_对pl/0作以下修改扩充。增加单词-程序员宅基地

文章浏览阅读2.1k次,点赞4次,收藏23次。第一次实验 词法分析实验报告设计思想词法分析的主要任务是根据文法的词汇表以及对应约定的编码进行一定的识别,找出文件中所有的合法的单词,并给出一定的信息作为最后的结果,用于后续语法分析程序的使用;本实验针对 PL/0 语言 的文法、词汇表编写一个词法分析程序,对于每个单词根据词汇表输出: (单词种类, 单词的值) 二元对。词汇表:种别编码单词符号助记符0beginb..._对pl/0作以下修改扩充。增加单词

android adb shell 权限,android adb shell权限被拒绝-程序员宅基地

文章浏览阅读773次。我在使用adb.exe时遇到了麻烦.我想使用与bash相同的adb.exe shell提示符,所以我决定更改默认的bash二进制文件(当然二进制文件是交叉编译的,一切都很完美)更改bash二进制文件遵循以下顺序> adb remount> adb push bash / system / bin /> adb shell> cd / system / bin> chm..._adb shell mv 权限

投影仪-相机标定_相机-投影仪标定-程序员宅基地

文章浏览阅读6.8k次,点赞12次,收藏125次。1. 单目相机标定引言相机标定已经研究多年,标定的算法可以分为基于摄影测量的标定和自标定。其中,应用最为广泛的还是张正友标定法。这是一种简单灵活、高鲁棒性、低成本的相机标定算法。仅需要一台相机和一块平面标定板构建相机标定系统,在标定过程中,相机拍摄多个角度下(至少两个角度,推荐10~20个角度)的标定板图像(相机和标定板都可以移动),即可对相机的内外参数进行标定。下面介绍张氏标定法(以下也这么称呼)的原理。原理相机模型和单应矩阵相机标定,就是对相机的内外参数进行计算的过程,从而得到物体到图像的投影_相机-投影仪标定

Wayland架构、渲染、硬件支持-程序员宅基地

文章浏览阅读2.2k次。文章目录Wayland 架构Wayland 渲染Wayland的 硬件支持简 述: 翻译一篇关于和 wayland 有关的技术文章, 其英文标题为Wayland Architecture .Wayland 架构若是想要更好的理解 Wayland 架构及其与 X (X11 or X Window System) 结构;一种很好的方法是将事件从输入设备就开始跟踪, 查看期间所有的屏幕上出现的变化。这就是我们现在对 X 的理解。 内核是从一个输入设备中获取一个事件,并通过 evdev 输入_wayland

推荐文章

热门文章

相关标签