在没有弹出对话框的情况下,您使用哪些技术在GUI中显示消息?
对于用户来说,弹出对话框通常非常糟糕 - 它们会妨碍您,并且您通常不会对导致错误感兴趣。另一种方法是忽略错误而不做任何事情但是,偶尔会有用户想知道他们何时导致错误...
因此,您希望显示信息性消息,但不要求用户必须单击烦人的弹出框。
一个选项可能是使用主窗口的状态栏,但为了让任何窗口小部件都能使用它,你需要传递对这个该死的状态栏的引用(我在这里想到了python / qt)。 。很快就会混淆并消除了“可恢复性”。您的小部件(想象您创建了另一个应用程序,没有状态栏,并且您想重用其中的小部件...)...
有什么想法吗?
答案 0 :(得分:1)
一个选项可能是使用主窗口的状态栏,但为了让任何窗口小部件使用它,你需要传递对这个该死的状态栏的引用
设计正确,情况并非如此。我的许多课程都有这样的日志信号: -
void Log(const QString& message, enum LogPriority priority);
优先级是枚举,用于定义信息级别,无论是调试消息,警告,错误,严重错误等。
另外,我有一个带有匹配日志槽的Logging类。您可以将其设为singleton,或者只使用static方法。
类将信号直接连接到日志记录类或父信号。这可以确保类不关心发送日志消息时会发生什么。您还可以通过删除其连接来禁用日志。
对于日志本身,Log类可以选择设置消息栏上的文本,写入文件,显示通知(OSX)或任何其他所需的方法。
虽然我的方法使用C ++,但我希望你可以在Python中做同样或类似的事情。
答案 1 :(得分:1)
我在QT / C ++应用程序中所做的是主窗口中的QDockedWidget,名为" Message Board",其中包含警告/错误/信息消息列表。无论如何,它可以被用户删除。为了不传递对这个QDockedWidget的所有小部件的引用,我使用(出于许多其他目的......)具有全局可见性的SharedData类,构建为应用程序的单例。所以每个小部件作为它的全局引用,可以设置错误或警告或其他:
Gshared->setError("oops!", ErrorType::Critical);
在setError函数中,我发出一个信号,由QDockedWidget中的一个插槽捕获(用于显示错误),由记录器管理器(在日志文件中写入有关错误的更多详细信息)等等...
另一种选择是"不再显示"自定义messageBox中的复选框。
答案 2 :(得分:0)
首先,消息和它的显示小部件是两个不同的东西。将它们组合在一起是一个严重的设计错误。
典型的解决方案是某种记录器/消息接收器,它是语义单例,但不一定使用单例模式实现。接收器可以是QObject
,以便您可以轻松地将消息源连接到接收器。然后可以将接收器连接到一个或多个显示小部件。
由于QObject
以及qApp
是全局实例指针而QCoreApplication
是QObject
这一事实,传递水槽非常容易。因此你可以:
通过动态属性系统传递指针,或
使接收器成为全局应用程序对象的唯一子项。
见下面的例子。请注意,Widget
只需要知道MessageSink
类的声明。它不需要显式传递任何实例。通常的单例模式也不是原样使用的。
class MessageSink : public QObject {
Q_OBJECT
public:
MessageSink(QObject * parent = 0) : QObject(parent) {}
Q_SIGNAL void message(const QString &);
static MessageSink * instance() { return qApp->findChild<MessageSink*>(); }
}
class Widget : public QWidget {
QVBoxLayout m_layout;
QLabel m_l1, m_l2;
public:
Widget(QWidget * parent = 0) : QWidget(parent), m_layout(this) {
m_layout.addWidget(&m_l1);
m_layout.addWidget(&m_l2);
m_l1.connect(MessageSink::instance(), SIGNAL(message(QString)), SLOT(setText(QString)));
m_l2.connect(MessageSink::instance(), SIGNAL(message(QString)), SLOT(setText(QString)));
}
}
int main(int argc, char ** argv) {
QApplication app(argc, argv);
MessageSink sink(&app);
Widget w;
w.show();
emit sink.message("Hello!");
return app.exec();
}
注意:拥有父级的本地QObject
不是错误。你只需要确保it gets destructed before the parent。 C ++保证在这里。