一、Qt Widgets 问题交流
1.QPushButton 双击与单击
QPushButton 自带的只有点击信号,可在 mouseDoubleClickEvent 中触发一个自定义信号。单击和双击最好不要做在同一个按钮上,判定的时间间隔不好定。
在 QML 中双击会触发一次点击和一次双击,QPushButton 如果也想做成这个效果,可以增加一个标志位,然后在 mouseDoubleClickEvent 中置位 true,mouseReleaseEvent 是判断是否双击触发不同的信号即可(双击事件在 release 之前进入)。
void MyButton::mouseReleaseEvent(QMouseEvent *event)
{
event->accept();
bool on_button = rect().contains(event->pos());
if(on_button){
if(dbClick){
emit buttonDoubleClicked();
}else{
emit buttonClicked();
}
}else{
emit buttonCancel();
}
dbClick = false;
}
void MyButton::mouseDoubleClickEvent(QMouseEvent *event)
{
event->accept();
dbClick = true;
}
二、Qt Quick 问题交流
1.QML Button/MouseArea 双击与单击
在 QML 中双击会触发一次点击和一次双击,如果只需要单击,可以在 release 事件处理中进行操作,不用 clicked 信号。
从源码可以看到,已经写死了双击后没法触发单击,只能自己在 release 信号进行操作了。
void QQuickAbstractButtonPrivate::handleRelease(const QPointF &point)
{
Q_Q(QQuickAbstractButton);
QQuickControlPrivate::handleRelease(point);
bool wasPressed = pressed;
setPressPoint(point);
q->setPressed(false);
pressButtons = Qt::NoButton;
if (!wasHeld && (keepPressed || q->contains(point)))
q->nextCheckState();
if (wasPressed) {
emit q->released();
if (!wasHeld && !wasDoubleClick)
trigger();
} else {
emit q->canceled();
}
if (autoRepeat)
stopPressRepeat();
else
stopPressAndHold();
wasDoubleClick = false;
}
void QQuickAbstractButton::mouseDoubleClickEvent(QMouseEvent *event)
{
Q_D(QQuickAbstractButton);
QQuickControl::mouseDoubleClickEvent(event);
emit doubleClicked();
d->wasDoubleClick = true;
}
2.Qt5 中 QML QtQuick.Dialogs 模块的文件对话框打开 U 盘路径后会导致占用
使用该模块的 FileDialog 打开 U 盘中的文件路径后,去操作弹出 U 盘会提示被占用,除非关闭当前程序。详见 Qt Bug:https://bugreports.qt.io/browse/QTBUG-55459
可以用 labs 中的对话框,不会有这个占用问题。在 Qt6 中 QtQuick.Dialogs 模块重写了很多,接口类似于 labs 模块的对话框,U 盘占用问题也没有了。从源码来看 Qt5 时该模块是放在 control1 的文件夹下的,而 control1 这个模块已经废弃,所以 Qt5 可以不用这个模块的文件对话框。
三、其他
1.关于Qt5中QAudioDeviceInfo获取可用输入输出设备的问题
以 audiorecorder 示例为参照,在输入设备列表可以看到名字一样的设备:
如果是带圆圈的R,另一个可能是乱码,这是因为 Qt5 Windows 版本有两个音频的插件。
其中,WASAPI 的接口只支持高采样率的录制,可以通过支持的采样率过滤:
auto infos = QAudioDeviceInfo::availableDevices(QAudio::AudioInput);
for (auto &info : infos)
{
//如过滤支持8k的
if (info.supportedSampleRates().contains(8000)) {
enable_list.push_back(info);
}
}