我正在尝试QDateEdit
允许QCalendarWidget
在请求时显示(而不是仅仅点击向下箭头)。例如,在我班上的某个地方我应该说:
ui.datepicker.showCalendar()
它应该加载日期选择器正下方的日历。
看起来我需要子类QDateEdit
,因为这不起作用:
QDateEdit *de = new QDateEdit();
de->calendarWidget()->show();
当你通过Qt的QDateTimeEdit.cpp源代码时,我也尝试过发送键盘命令,但似乎我的键盘快捷键被禁用了。
关于我要对子类做什么以使其发挥作用的任何想法?我想的是:
class MyDateEdit : QDateEdit
{
Q_OBJECT
protected:
void mouseEvent(QEvent *event) {
this.calendarWidget().show();
}
};
但是唉似乎也没有编译或正常工作。
答案 0 :(得分:10)
在QDateTimeEdit中启用“setCalendarPopup(bool enable)”允许弹出日历
答案 1 :(得分:1)
我能够自己解决这个问题 - 仍然不确定如何使QDateEdit正常工作,但我使用的是QLineEdit,它符合我的需要。只需将QCalendarWidget的“onClick(QDate)”连接到您创建的插槽即可:
setText(date.toString("M/d/yyyy"));
ui->calendar->hide();
然后使用执行“ui-> calendar-> show();”的“OnFocusIn”事件向QLineEdit添加事件过滤器请参阅:Get a notification/event/signal when a Qt widget gets focus
答案 2 :(得分:0)
@Rob S answer
你使用事件过滤器方法是对的,我们会对QDateEdit做同样的事情。
我正在编写使用QDateEdit扩展您的方法的代码:
在mainwindow.h中我创建了一个QCalendar指针(使用QtCreator)
以下是mainwindow.cpp的代码(我发布了完整代码,以便像我这样的新手可以从中受益)
确保将buttonSymbol和calendarpopup属性设置为false以使其正常工作
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QCalendarWidget>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->dateEdit->setDate(QDate::currentDate());
widget=new QCalendarWidget(); //widget is QCalendar pointer
ui->verticalLayout->addWidget(widget);
widget->setWindowFlags(Qt::Popup); // we need widget to popup
ui->dateEdit->installEventFilter(this);
connect(widget,SIGNAL(clicked(QDate)),ui->dateEdit,SLOT(setDate(QDate)));
}
MainWindow::~MainWindow()
{
delete ui;
}
bool MainWindow::eventFilter(QObject *object, QEvent *event)
{
if (event->type() == QEvent::InputMethodQuery)
{
if (object == ui->dateEdit)
{
if(widget->isVisible()==false && ui->dateEdit->calendarWidget()->isVisible()==false) // this done to avoid conflict
{
qWarning(QString().number(event->type()).toStdString().c_str());
qWarning(object->objectName().toLatin1().data());
widget->move(ui->dateEdit->mapToGlobal(QPoint(0,ui->dateEdit->height())));
widget->show();
}
}
}
return false;
}
OR ::或者我们可以使用dateEdit提供的QCalendarWidget,虽然它的效率不高,因为Popup会将其内部混乱。如果你想要试一试
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QCompleter>
#include <QCalendarWidget>
#include <QMouseEvent>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->dateEdit->setDate(QDate::currentDate());
widget = ui->dateEdit->calendarWidget();
widget->setWindowFlags(Qt::Popup);
ui->dateEdit->installEventFilter(this);
//connecting widget with dateedit
ui->dateEdit->setButtonSymbols(QAbstractSpinBox::NoButtons);
ui->dateEdit->setCalendarPopup(true);
connect(widget,SIGNAL(clicked(QDate)),ui->dateEdit,SLOT(setDate(QDate)));
}
MainWindow::~MainWindow()
{
delete ui;
}
bool MainWindow::eventFilter(QObject *object, QEvent *event)
{
if (object == ui->dateEdit)
{
if (event->type() == QEvent::FocusIn || event->type() == QEvent::MouseButtonPress)
{
// WE NEED MOUSE EVENT TO AVOID INTERFERNCE WITH CALENDAR POPUP BUTTON SITUATED AT CORNER OF dateEdit WIDGET
if(widget->isVisible()==false && ( ((QMouseEvent* )event)->x()< (ui->dateEdit->width()-10)))
{
widget->move(ui->dateEdit->mapToGlobal(QPoint(0,ui->dateEdit->height())));
widget->show();
}
}
}
return false;
}
答案 3 :(得分:0)
我想提供与@Dr类似的选项。 Xperience的answer将日历小部件封装在QDateEdit子类中:
#include <QDateEdit>
#include <QCalendarWidget>
class DateEdit : public QDateEdit {
Q_OBJECT
public:
explicit DateEdit(QWidget *parent = nullptr);
protected:
virtual void focusInEvent(QFocusEvent *event) override;
private:
QCalendarWidget *calendar = new QCalendarWidget(this);
};
DateEdit::DateEdit(QWidget *parent) : QDateEdit (parent) {
setButtonSymbols(QAbstractSpinBox::NoButtons);
setCalendarPopup(false);
setDate(QDate::currentDate());
calendar->setWindowFlags(Qt::Popup);
connect(calendar, &QCalendarWidget::clicked, this, [&](const QDate &date) {
setDate(date);
calendar->hide();
});
}
void DateEdit::focusInEvent(QFocusEvent *event) {
if (!calendar->isVisible()) {
calendar->setSelectedDate(date());
calendar->move(mapToGlobal(QPoint(0, height())));
calendar->show();
}
return QDateEdit::focusInEvent(event);
}
警告::如果使用QtDesigner放置此小部件,它将覆盖buttonSymbols和calendarPopup属性,因此必须手动设置它以隐藏QDateEdit的按钮。
答案 4 :(得分:0)
这是我处理此问题的方法。经过一段时间的努力争取干净的东西后,我阅读了QDateEditor
的源代码(实际上只是简化的QDateTimeEditor
),这似乎不是干净的解决方案。以下是toggle()
而非show()
的代码,但仍然:
// Enable the calendar popup
date_editor->setCalendarPopup(true);
// Show the calendar popup by default
// There seems to be no proper interface to achieve that
// Fake a mouse click on the right-hand-side button
QPointF point = date_editor->rect().bottomRight() - QPointF{5, 5};
QCoreApplication::postEvent(
date_editor,
new QMouseEvent(QEvent::MouseButtonPress, point, Qt::LeftButton,
Qt::LeftButton, Qt::NoModifier));
使用类似的方法,您可以继续依赖编辑器的验证功能。
顺便说一句,有关内置编辑器的另一件令人讨厌的事情是,它引诱QLineEdit
是(至少就我而言)默认情况下不显示键盘光标。这非常令人困惑。为了解决这个问题,我做到了:
// Select a section so that the cursor is be visible
date_editor->setSelectedSection(QDateTimeEdit::DaySection);
此课程或课程选择日期的日期部分,但是如果使用键盘箭头,则选择消失,但是可以看到键盘光标。